This starts to get confusing with all the Interbase and PostgreSQl stuff being mixed.
Fr0sT wrote:Actually I examined IBX code and it seems Zeos' ZIBEventAlerter.pas code is almost 100% copy of IBEvents.pas... o_O I'm really unsure this is OK without even a note in unit header. Probably both versions are inherited from FIB but I don't know the truth.
If the the Zeos ZIBEventAlerter.pas really started out as a copy of IBX IBEvents.pas, we might be in trouble because these files were distributed under the InterBase Public License Version 1.0. That't what the original IBEvents.pas says. I doubt that the InterBase Public Licens allows to reuse their code with any other license we wish.
I tried to dig up some information on that. The ZIBEventAlerter.pas started its life as an extra unit supplied by somebody else. It was integrated into Zeos by mdaems after he found it. See the following link:
http://zeoslib.sourceforge.net/viewtopi ... 7151#p7151
So it seems that it is not 100% clear on how this unit appered in Zeos. Honesly I like to think that the original author surely was inspired by the original IBEvents.pas but decided to hav his own implementation. There are quite some differences in the component interface and the naming of the procedures.
"Borrowing" code from an IBX fork seems to be a bad way to go - at least until we know if we can copy code that is under the IPL into Zeos.
Wild_Pointer wrote:I did consider raising exceptions if error is not hadled initially, but then realized that this way I would change current behavior of the component and decided playing safe. The other reason - I've found no way (strangely) to handle exceptions from timer events on Lazarus... TApplicationProperties did not catch the exception...
That said maybe isHandled is not needed? Lets do:
Code: Select all
...
try
CheckPostgreSQLError(...);
except
on E: EZSQLException do begin
if Assigned(FOnError) then FOnError(self, E.Message);
end;
end;
Hmmm honestly I don't care if components change behaviour for Zeos 7.3. For Zeos 7.2 it is a different story. Your proposed code just swallows all exceptions that happen - at least all EZSQLExceptions. So if I don't install an error handler everything will look as if it works although it doesn't. For me I have to say, I dislike that. I like programs and components that hit me in the face when something is wrong. This way I at least know that something is wrong. Keeping that in mind my sugestion for this is like this:
- Disable the timer
- Do the work
- Check for errors, throw an exception if there is an error and no error handler
- reenable the timer if there is no error -> For me there is no reason to check for new events if we already had an error.
How did you check the thing about Exceptions with Lazarus? Today I did a very simplistic test with a TTimer that raised an exception. For me it behaved like it should - I got the exception error message. Did I misunderstand you there?
Fr0sT wrote:I doubt that throwing an exception is necessary here.
How should we handle errors that are not taken care of? How should the developer know that something went wrong?
Fr0sT wrote:Moreover, I personally dislike the very idea of doing potentially long blocking operations in OnTimer as it will freeze the main thread until the polling is completed. IBX way with background thread seems smarter.
Honestly I think that if a check for errors shows some errors a potentially freezing main thread will be your smallest problem.
Also raising errors can only be done in the main thread because our components live there. For PostgreSQL I am not sure if older versions of libpq are thread safe. Honestly I don't even know that for the current version. We should check that before we try to implem,ent threading there.
Fr0sT wrote:But here an architectural decision is required: what level of changes is enough. Simple patch is easy but some issues remain. The deepest change would be a common interface for background thread and event component, from which any DBC-specific implementation would inherit.
Hmm. I doubt that all libraries we use are thread safe. Even if they are, libraries for future drivers might not be. So if we do something architectural about events I suggest we keep a structure where the driver gets to decide if it wants to use a separate thread for checking for events.
What do you think?