Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Yaron last won the day on November 13 2018

Yaron had the most liked content!

Community Reputation

28 Excellent

Technical Information

  • Delphi-Version
    Delphi 10.3 Rio

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Yaron

    FireBird, TFDConnection and concurrency

    You beat me to it, I just found this: https://mathiaspannier.wordpress.com/2016/07/17/how-to-properly-cleanupshutdown-a-delphi-isapi-which-uses-threads/ Which is essentially the same answer, can't close the connection in the finalization section when dealing with ISAPI.
  2. Yaron

    FireBird, TFDConnection and concurrency

    Looks like I'm encountering an IIS issue when using this scheme. In the ISAPI's DLL's finalization code I call "FDManager.Close" and in IIS, when stopping the application pool associated with the DLL it can take ~60 seconds before I can restart the pool, any ideas? This is the error I get: When checking my logs, It doesn't seem to exit cleanly (the debug message that the "DB Closed" does not show up in the log), but there doesn't seem to be an exception, here's the code I use: Try FDManager.Close; Except on E : Exception do {$IFDEF TRACEDEBUG}AddDebugEntry('Exception disconnecting from DB : '+E.Message){$ENDIF}; End; {$IFDEF TRACEDEBUG}AddDebugEntry('DB Closed');{$ENDIF} When I run the same code locally as an EXE that handles the HTTP requests, there are no issues, any ideas?
  3. Yaron

    FireBird, TFDConnection and concurrency

    Thank you! Took me a bit to understand the mechanics, but with your help I managed to rewrite the code with minimal changes and so far it's working. P.S. "FDManager.Active :=True;" no longer works in Delphi 10.3, it simply doesn't exist anymore, but "FDManager.Open" seems to be the replacement.
  4. Yaron

    FireBird, TFDConnection and concurrency

    Does that mean that for every http request (that requires DB access) I have to create a new instance of TFDConnection and then connect to the DB? This is the first time I'm writing an ISAPI dll with DB access and the threading model is not exactly clear to me. My original (perhaps flawed) assumption was that IIS will load additional DLLs in separate threads to handle concurrent http requests. I would like to avoid the 100ms penalty for connecting to the DB on each request, any tips?
  5. I am trying to build a system that will handle concurrent DB requests efficiently, there's not a lot of load, but it should be able to handle more than 1 query concurrently. I am using FireBird v3.0.4 and Delphi 10.3.2 with the TFDConnection component. I am hosting the code in an ISAPI DLL that runs on IIS 7.5. Right now I'm creating the DB connection using TFDConnection in the DLL's "initialization" section. However, I noticed that even under low-load (2-3 users), I occasionally get an "[FireDAC][Phys][FB]Error reading data from the connection." exception when performing a DB query (not the same DB query, it seems pretty random). I tried to research the error and didn't find anything clear, the best I got was : https://forums.embarcadero.com/thread.jspa?threadID=245750 Which seems to indicate that I should instance a copy of TFDConnection for every query. Before I make significant code changes to test this, I would welcome any tips on the best approach to handling DB concurrency.
  6. Not my quote: I basically used it cause that's the example I was able to find in the documentation for exporting the DB. In theory I could have used the windows task scheduler, but I needed more control and I'm using the service to perform other timed DB actions. And I couldn't just call nbackup directly from the task scheduler as I'm erasing old DB files and numbering new backups based on existing backup file names (a running counter in the file name) and some more logic is required for this.
  7. SyncThing has a Linux/Mac/FreeBSD/etc... client, so in theory the off-site backups can be on pretty much any widely used OS.
  8. It took me hours of research to find the tools & documentation and haven't found any up-to-date text describing a similar process, so I decided to post my findings here in case someone else has the same requirement. I wrote (in Delphi) a simple windows service that runs the FireSQL "nbackup.exe" command line tool to create a DB backup every [x] hours using this command line: "c:\Program Files\Firebird\Firebird_3_0\nbackup.exe" -U SYSDBA -P [password] -B 0 "c:\path\database.FDB" "[output_file]" The windows service keeps [x] number of backup files (erasing old files) and creates a new backup every [y] minutes. Personally, I used 1 full-db backup per hour, covering an entire week (168 files). I then use the open-source SyncThing P2P file sync tool (also running as a windows service) to securely & automatically sync the DB backups with every PC assigned as off-site backup. 100% automated, secure, zero cost.
  9. This is a bit old, but I've been blocking the windows screen-saver for media playback in every version of windows since 1999. I'm actually handling several actions, first I capture the WM_POWERBROADCAST message in the form: procedure WMPOWERBROADCAST(var M : TMessage); message WM_POWERBROADCAST; const PBT_APMQUERYSUSPEND = $0000; PBT_APMQUERYSTANDBY = $0001; PBT_APMQUERYSUSPENDFAILED = $0002; PBT_APMQUERYSTANDBYFAILED = $0003; PBT_APMSUSPEND = $0004; PBT_APMSTANDBY = $0005; PBT_APMRESUMECRITICAL = $0006; PBT_APMRESUMESUSPEND = $0007; PBT_APMRESUMESTANDBY = $0008; PBT_APMBATTERYLOW = $0009; PBT_APMPOWERSTATUSCHANGE = $000A; PBT_APMOEMEVENT = $000B; PBT_APMRESUMEAUTOMATIC = $0012; begin Inherited; Case M.WParam of PBT_APMQUERYSUSPEND, PBT_APMSUSPEND : Begin If SystemSuspended = False then Begin SystemSuspended := True; End; End; PBT_APMRESUMEAUTOMATIC : Begin SystemSuspended := False; End; End; M.Result := Integer(True); end; Then on WinMsg (Application.OnMessage := WinMsg;) I do: procedure TMainForm.WinMsg(var Msg: TMsg; var Handled: Boolean); var ModWnd : HWnd; I : Integer; mPos : TPoint; begin If (Msg.Message = SC_SCREENSAVE) or (Msg.Message = SC_MONITORPOWER) then Begin Msg.wParam := 0; Msg.Message := SC_Move; Handled := True; End else If (Msg.Message = WM_SYSCOMMAND) then Begin Case Msg.WPARAM of SC_MONITORPOWER, SC_SCREENSAVE : Begin Msg.wParam := 0; Msg.Message := SC_Move; Handled := True; End; End; End; End; Then on WndProc ( procedure WndProc(var Msg : TMessage); override;) : Hope this helps.
  10. Took your advice and created a QC report: https://quality.embarcadero.com/browse/RSP-26253
  11. It's not an issue restoring the IDE, just a little drag on that line, but it happens about once or twice every day which is a bit annoying.
  12. To give me the largest work-space, I designed the Delphi IDE UI to look like the attached "delphi_before.jpg". However, under some conditions, windows throws apps a resize event (e.g. when turning on a secondary monitor), and then the Delphi IDE UI automatically changes to the attached "delphi_after.jpg" (the tool-bar drops down a row). Is there any way to lock the UI so my preferred layout remains fixed? P.S. This is on Win7 64bit.
  13. Nevermind, I figured it out, I had to move the charset code after setting the email body.
  14. Another bit of information, when looking at the headers of the delivered email, there's this: Content-Type: text/html; charset=us-ascii Even though CharSet is set to UTF8. According at this post https://stackoverflow.com/questions/9844250/not-able-to-send-utf-8-email-using-delphi-indy , I'm setting the parameters in the right order.
  15. If I try to use UTF8Encode in Delphi 10.3 I get a warning "[dcc32 Warning] xxx.pas(683): W1057 Implicit string cast from 'RawByteString' to 'string'".