Tuesday, June 12, 2018

Erik Meijer on Agile

That's exactly what I think about Agile

Not that I think everything about Agile is bad. But the bad parts took over and what's left is not much better than nothing. Probably worse.

Friday, June 8, 2018

Delphi fix up mechanism

There are a few methods and functions in Classes.pas unit which take care of something that I call "fix up mechanism". Just search for "fixup" inside Classes.pas and you will find them. The fix up mechanism exists to "fix" (really?) references to other components which are owned by a different container, when they are created at runtime, loaded from a DFM resource.

So, let's say you have a ADOQuery1 contained in DataModule1. Then you have Form1 which contains DataSource1 which in turn references ADOQuery1 through DataSet property. This relationship could be set at runtime as:

Form1.DataSource1.DataSet := DataModule1.ADOQuery1;

However, most Delphi developers choose to set this relationship at design time, using Object Inspector. This has some advantages - it requires zero code - but also its disadvantages - it requires that some mechanism "fixes" this reference at runtime. So, when you create Form1 at runtime, it also creates/loads DataSource1. Inside the DFM file you will find that DataSource1.DataSet contains a reference to DataModule1.ADOQuery1 - referenced by name. But when the form loads from DFM, the Delphi runtime library doesn't know how to set this property. The form (a DFM resource at this stage) only contains a string (DataModule1.ADOQuery1) but RTL needs to find the actual object and set the reference accordingly. That's the fix up mechanism mission.

Most Delphi developers never worried about this (they probably don't even know about it) because (a) it works transparently and very well and (b) it doesn't have any effect on performance of most applications. When I say "most" I mean, desktop applications. It definitely may have some - important - influence on multi-threaded applications created with Delphi because it uses a global lock, implemented as a TMultiReaderExclusiveWriterSynchronizer. If your application contains, for instance, TDataModules loading from DFM resources this effect can be serious.

Let's say you have some server application (it might be a DataSnap server, COM+, WebBroker, whatever) which loads DataModules from DFM files. For example, WebModules *are* DataModules. If all objects contained in that DataModule reference other objects contained in the same DataModule, you are also safe. However, if one component references another component in another DataModule, the fix up mechanism will need to do its job and the nasty global lock will occur. 

If your application receives several requests at the same time and 2 or more requests require the creation of one instance of such DataModule, the first one will acquire the global lock and the second will have to wait until the fix up finishes (and unlocks the global list), so it can proceed and lock the fix up list again. There is another - more complicated - scenario where this global lock might create some deadlock situation if you also have other global locks (e.g. Critical Sections) being used at the same time.

So, my first recommendation is "never link objects owned by different containers at design time in a multi-threaded application". If you link them via code it will perform better and also save you from a possible deadlock which - believe me - is very very hard to find and almost impossible to reproduce in a controlled environment. As a bonus you will never have that nasty surprise when you find out - in production, of course - that your DataSource1 is not pointing to DataSet1 anymore because, God knows how, the DataSet property is blank (who never experienced that?)...
Link objects via code!! OnCreate event of Forms and DataModules are good places to put that linkage code.

Sometimes I know that it is hard to change the whole application. Your application is ready, tested and you don't want to risk such a core change now. That's fine. If your application is an IntraWeb application you can turn on our - still experimental - new feature which replaces the global fix up mechanism completely, with a new, much more scalable and thread-friendly one. To turn it on you should set TIWServerControllerBase.FixupPatchEnabled* to true, before starting your application. The best place to do it is in your .DPR file. Example:

  TIWServerControllerBase.FixupPatchEnabled := True;

That should do it. Have in mind that it might need some adjustments in your application but, in general, it should work in most cases.

Available in IntraWeb 15 only.

Thursday, June 7, 2018

Back to business

After a long long period of inactivity, I'm back to business. I'll publish some new stuff here, probably some IntraWeb related material as well.

Actually I have plans to create a brand new IntraWeb application to host some documentation about IntraWeb itself. It will contain new stuff and I intend to make a *really nice* IntraWeb application to handle it.

Wednesday, March 1, 2017


Back in 2013, Marco Cantu wrote this blog post:


Simon Kissel, a very active and respected member of the old Delphi community posted a comment which I find very relevant and I want to emphasize here. If you are interested in Simon's Delphi story, you can read his alternative (and controversial) Delphi roadmap, here:


Marco also commented on Simon's roadmap, here:


I don't recall all the details right now, but this roadmap did some very loud noise at that time... You can google for it and find lots of stuff....

Anyway, here is Simon's comment about Marco's take on string immutability, among other things (abominations) like, AnsiString removal/deprecation. I think Simon's comments are *more relevant than ever*.

Of Strings, Immutability, COW, and AnsiStrings

Excuse me, but you are not "adding features". You are breaking compatibility of 100% of all Object Pascal code existing today, without any benefit at all. The decision for 0-based strings would have needed be done 20 years ago. Today it's plain silly. Mutability, copy-on-write and the excellent string performance always has been one of the very few actual language advantages over pretty much all the competition. This is easy to learn, easy to remember, clean and nice, and produces fast code: s1 := s1 + ' ' + s2; This is hard to learn, hard to remember, dead ugly, and produces slow code: s1 := TStringBuilder.create(s1).append(' ').append(s2).ToString; Also, "help maintaing code on very old version of Delphi" - that's also completely off. Check the Delphi version survey. A large chunk of users still is using Delphi 7 - for example me, because I need Linux compatibility. Do you want to give them an incentive to finally move to your current offerings and pay you money, or do you want to give them an incentive to drop Delphi and move elsewhere? And: It is about time for Embarcadero that they are no longer the market leader in the Object Pascal field, which already is a nichĂ© due to how Delphi and the language got handled the recent years. There are other players, which have stopped copying most of the not-so-clever language extensions of the past years. If you make yourself incompatible with other Object Pascal compilers, you will no longer hurt the competition, you will only hurt yourself. It's a guarantee you'll never get back any users from FreePascal/Lazarus anymore. The "we want to attract new users by making our language look more modern"-stuff doesn't work either. You are a Delphi book author. You very well know that *all* of all available literature on Delphi and Object Pascal in the world teach Delphi Strings. Whoever is new to the language will learn something to then find out that you've broken it. This is a terrible new user experience. Long story short: In the great tradition of the recent years, what you guys do *simply does not make sense business-wise*. You are fractioning the ecosphere you live in. That's an insane strategy. You should revert it. And finally a rant about the implementation aspect: Delphi strings can be implemented in LLVM without any problems and with good performance. Others have done it. There is no technical reason for all this. Whoever is writing your NextGen compiler must either incompetent, lazy, underfunded or very new to the object pascal language. Sorry for the harsh words, but LLVM takes 90% of the work a compiler engineer has to do. If you fail on the remaing 10%, you should not be a compiler engineer.

Monday, January 25, 2016

My Delphi code on Bitbucket

Finally I started using Bitbucket as a repository to my personal projects. Some are free, like the MergeSort algorithm, and the FastStringReplace unit. Soon I'll publish one more project that I've been working on during the last month...

So here they are:



Thursday, August 20, 2015

Crappy Windows Media Player in Windows 8

Microsoft still didn't get it. The most crappy media player of all times. I guess Win 10 is even worse!

Remove it for good:

Go to "Control Panel\Programs\Programs and Features" and click on turn windows features on or off

Uncheck Windows Media player and click OK

Then Yes...

Wait until it completes. Then reboot and voilá!

Install WinAmp 2.95 and be happy!

Sunday, June 14, 2015

Fast StringReplace fix

I did a small and silly mistake in my original FastStringReplace implementation that could cause the FastStringReplace() routine to fail completely when rfIgnoreCase was used and the OldPattern was already in upper case.
The bug is fixed and I'm also writing a unit test for it. If you are already using FastStringReplace in your code, please update using latest version.

Direct download link here.