I've been playing with AQTime for a little over 1 week now. All in all, I love it. My company bought 2 licenses because we saw the potential in the product.
Here are the things I like so far:
- Support. The people on their newsgroups are fantastic.
- The GUI. They make liberal use of DevExpress components throughout, and do so quite capably.
- The new Assistant window that helps guide you through the profiling process.
- The samples and documentation.
The things I don't like so far are greater - not necessarily in number, but in quality.
- Leaked Delphi objects are reported as "VCL native memory.N", where N is the number of VCL objects that have been created so far. AQTime 3 reported the actual object name here.
- If you use run-time packages (at least with Delphi 6), AQTime 4 won't show you any leak information. AQTime 3 showed me leak information without fail. According to Atanas, the next version of AQTime 4 should fix this problem.
- In AQTime 3, they used to have a profiler called Reference Count Profiler. This would help you identify bad AddRef/Release lifetimes. The
claim is that AQTime 4 can get by without this, but I'm not sold yet - especially given the first 2 points.
- I have a support issue open trying to get DCOM Server support done properly in AQTime 3.
Now, I realize that I'm just coming up to speed with this product, and this may very well be a case of RTFM and/or learning curve. I reserve the right to move things from the "like" to "don't like" category as I learn more about this very powerful product. But the bottom line is that, for
most of our profiling right now, we are using AQTime 3, as it seems a bit more capable than AQTime 4.
During my perusal of their newsgroup, I noticed a little tidbit that said something to the effect of: AQTime 4 is a new version of AQTime that
merges together the old Unmanaged profilers and the newer .NET profilers. During the effort to get AQTime 4 produced, they understandably looked for ways to improve the product. They probably shared new codebases, consolidated the list of profilers, etc. The combination of all these things means that I'm waiting for patches to AQTime 4 before I can use it to it's fullest extent. I know of Atanas' well-deseverd and excellent reputation in the Delphi community, so I'm not worried that I'll never get what I want. I just hope it's sooner rather than later.
Everything is set. Here is the information on the Delphi 2005 launch event in Milwaukee.
John Kaster will be presenting a free session on Delphi 2005. It will run from 6:00-8:00 pm on 12/21/04 at the Marriott West in Pewaukee. That page should get you there with only slight problems. For some unknown reason, the civil engineers in the area decided to rename a bunch of highways out here, so pay close attention to the orange signs under the exit signs. "Former Highway 164 North" is now Highway F North, I believe. Or, just pay attention and take Exit 295 (as they mention in the directions on the web page).
In addition to getting some great information, John will be bringing Christmas spirit with him, and act as Santa Claus for the evening. There will be free T-shirts and other goodies to give away, flyers and marketing materials on Delphi 2005, feedback forms to let Borland know what we think, rebate coupons good for 25% off Delphi 2005 purchases (must be present to receive one; they are time limited (no immediate details - John thought they might be good through the end of this month or next, and John also thought it covered up to 4 copies - read the form when you get there for the final word ), a drawing to give away a Delphi 2005 Architect, and depending on attendance, a drawing for 1 or more Delphi 2005 Pros. How's that for a run-on sentence?!?
I will be emailing everyone on my list with this same information. Feel free to email me if you need to change your RSVP, or if you know of anyone else who wants to show up. It looks like we're going to have a great turnout. Thanks everyone, and I look forward to seeing you all there!
Using DBX, we came across a bug where the values for the fields in the first record were not available in the OnCalcFields event. After doing some digging, I found that this was already reported as QC 1328. I noticed that the problem was marked as Fixed in Delphi 2005, and we are still using Delphi 6, so that would explain it.
I then went and modified my own test case, and the one reported in QC and noticed that both of these test cases still exhibited the problem in D2005. I talked to a couple of friends in Scotts Valley, and they confirmed the behavior as still being present in Win32 in D2005. So, it turns out that the fix only made it to the VCL.NET side of things. At least that source is similar enough to figure out what's going on.
The problem exists in TDataset.GetCalcFields. Take a look at the VCL.NET implementation in D2005 for the complete code. However, I still needed to get the fix into our codebase, and we won't be upgrading everything to D2005 for a little bit yet. We also can't just patch the VCL in the DB.pas unit since we are using runtime packages on our app servers in order to pass VCL components around.
With all of these requirements in place, I set out to create a descendant of TSQLQuery and override GetCalcFields. This turned out to be problematic, however, due to the fixed code's need to set the FEOF private variable in TDataset. I realized that the EOF property is read-only and that the backing field is private, so I used Hallvard's Hack #1. This works absolutely flawlessly, and I now have the fix isolated to one place so that when we upgrade to D2005, I can simply remove this new component in the handful of places that it gets used.
Here is the implementation code that I finally came up with:
type
TDatasetEx = class(TDataset)
published
property EOF;
end;
procedure TDRMSQLQuery.SetEOF(Value: boolean);
begin
PBoolean(Integer(Self) + (Integer(GetPropInfo(TDatasetEx, 'EOF').GetProc) and $00FFFFFF))^ := Value;
end;
{$WARNINGS OFF}
// We are guaranteed that the only time we both set and use eofBak is when
// State = dsInactive. Therefore, we don't care about the warning.
procedure TDRMSQLQuery.GetCalcFields(Buffer: PChar);
var
eofBak: Boolean;
begin
if (State = dsInactive) then
begin
eofBak := EOF;
SetEOF(False);
end;
try
inherited GetCalcFields(Buffer);
finally
if (State = dsInactive) then
SetEOF(eofBak);
end;
end;
Notes:
- I would fully expect that Borland will fix this fully in an upcoming D2005 patch.
- Thanks to Joerg and John (from Borland) for helping out with this one.
- The problem does not exist in the BDE, just DBX. I haven't checked other data access layers (ADO, IBX, DOA, etc.), but if they have the same problem, then you can use something like this technique to fix it for now. Since the true fix is in TDataset, all other implementations will be fixed automatically when that fix is rolled out.
I couldn't help myself. There I was, looking at the iPods, and the next thing you know it's purchased and at my house. There must be some kind of mind control device on those things! Still, it is one incredible mp3 player. I wrote a couple of small utilities to interface with iTunes via the COM SDK. Of course, I used Delphi to write the code.
I just came across this blog entry, talking about managed access to iTunes. If you follow the links from that page, there are some more code samples.
Thanks to Steve Trefethen, who pointed me to this link:
Delphi 2005 Architect Packs A Wallop
All in all, a very positive review of Delphi 2005. I've been pretty happy with how things have been working here, too. Although, to be fair, I'm not using it as my primary IDE right now. Basically, I've upgraded custom components, compiled smaller utilities, etc. in preparation for the migration of the entire team to go to Delphi 2005. We can't even begin to think about that, though, until DevExpress provides D2005 versions of their libraries.
As I mentioned earlier, I love FinalBuilder. I am always looking for ways to put more into FinalBuilder. One thing that I noticed during deployment of builds to target server machines is that I am still doing some manual steps to unregister the COM servers before copying via FinalBuilder, and then registering the COM servers after the copy is complete. I do this to make sure that if a user decides to try and connect to the app server during the time that I am copying the build up, they don't get through.
I have a BAT file that unregisters and uninstalls services that I use to do this. But this means that I need to do this on the target machine. I did some digging and came across PSExec from SysInternals. This file will let you execute commands on a remote machine. After some tweaking, I came up with the following command that I am now using in FB to take care of remote COM registration tasks.
psexec \\%TARGET_SERVER% -u Administrator -p MyAdminPassword -w c:\Servers cmd /c unreg_servers.bat
This works very well, and it's one more thing that I now have under the control of FinalBuilder. I also use SysInternal's PSService utility to remotely control the services.
One of the big dilemmas programmers face every day is "Should I write this code as quickly as possible or should I write it to be as robust as possible?". Deadline pressures make some pick the quick option too often. :-( That's why I was pleasantly surprised to find CodeSmith. CodeSmith is a template-based code generator that can output code that can then be used in any ASCII based language (e.g. Delphi).
During development, there are plenty of times when you need to create a collection of objects. For example, you have a TCustomer object and need a TCustomerList object to store a list of those objects. You have a lot of options on how to represent this. Here are some of those options:
- Place the TCustomer objects in a TList. You need to typecast the code, and you can put any object in the list. Plus, you have to worry about object lifetimes.
- Use a TObjectList instead of a TList. This allows you to not worry about object lifetimes, but the rest of the problems using a TList still exist.
- Use a TStrings object (e.g. TStringList), and add your object in to the Objects property
- Create a custom list class, where you don't have to worry about type safety or object lifetime
Unfortunately, the last option is rarely chosen due to time constraints. It doesn't take all that long to do, but if you have to stop what you're doing to create the custom class, it doesn't get done more times than not.
To solve that, I created a CodeSmith template to generate strongly typed collections. Download my template, install CodeSmith, play with it, and let me know what you think. I can think of some nice improvements, like adding comments (along with an option to include those comments or not). After I get some feedback on this, I plan to upload it to the CodeSmith File Share forum.
On December 21, 2004 from 6:00-8:00 pm, John Kaster will be coming to Milwaukee, WI to show off Delphi 2005. Location is still to be determined, but most likely will be in the Pewaukee/Waukesha/Brookfield area. The event is free, and if you're using Borland tools (or want to know more about life outside the MS camp), you should really find a way to get there.
Please send me an email if you are interested in attending. Response has been fantastic so far. Let's welcome a transplanted Wisconsinite back home in style!
|