PQConnection not closed on TDatamodule.Free; lazarus / 16-Databases ---------------------------------------------------------------------- martinrame · 2022-11-09 17:03 Hi, I have a command line application (TCustomApplication descendant) that has a TDataModule where I connect to 2  PostgreSql databases using TPqConnection. In the .lpr file I start the application using this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var                                                                                                                                                                                                                                    Application: TEmailSender;                                                                                                                                                                                                           begin                                                                                                                                                                                                                                    Application:=TEmailSender.Create(nil);                                                                                                                                                                                                 Application.Title:='Email sender';                                                                                                                                                                                                     Application.Run;                                                                                                                                                                                                                     DataModule1.Free;                                                                                                                                                                                                                      Application.Free;                                                                                                                                                                                                                    end. And the dm.pas is this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TDataModule1.DataModuleDestroy(Sender: TObject);                                                                                                                                                                             begin                                                                                                                                                                                                                                                                                                                                                                                                                                    PQConnection1.Close(True);                                                                                                                                                                                                             PQConnectionDicomSCP.Close(True);                                                                                                                                                                                                      writeln('DataModule Destroy');                                                                                                                                                                                                         inherited;                                                                                                                                                                                                                           end;                                                                                                                                                                                                                                                                                                                                                                                                                                                                          procedure TDataModule1.DataModuleCreate(Sender: TObject);                                                                                                                                                                              begin                                                                                                                                                                                                                                    PQConnection1.HostName:= '127.0.0.1';                                                                                                                                                                                                    PQConnection1.DatabaseName:= 'db1';                                                                                                                                                                                            PQConnection1.UserName:= 'postgres';                                                                                                                                                                                                   PQConnection1.Password:= 'postgres';                                                                                                                                                                                                     PQConnection1.Connected:= True;                                                                                                                                                                                                                                                                                                                                                                                                                                               PQConnectionDicomSCP.HostName:= '127.0.0.1';                                                                                                                                                                                           PQConnectionDicomSCP.DatabaseName:= 'db2';                                                                                                                                                                                        PQConnectionDicomSCP.UserName:= 'postgres';                                                                                                                                                                                            PQConnectionDicomSCP.Password:= 'postgres';                                                                                                                                                                                            PQConnectionDicomSCP.Connected:= True;                                                                                                                                                                                                 writeln('DataModule Create');                                                                                                                                                                                                        end;                                                                                                                                                                                                                                                                                                                                                                                                                                                                        initialization                                                                                                                                                                                                                           DataModule1 := TDataModule1.Create(nil);                                                                                                                                                                                                                                                                                                                                                                                                                                    finalization                                                                                                                                                                                                                             DataModule1.Free;   As you can see, in TDataModule1.DataModuleDestroy I added  writeln('DataModule Destroy'); to "see" if it was destroyed, and indeed it was, but the database keeps accumulation connections in "idle" state until the number surpasses 250, where it starts rejecting them. How can I correctly end a database connection? ---------------------------------------------------------------------- MarkMLl · 2022-11-09 17:22 Just to get the ball rolling, can I check one thing here: when you refer to a database in the current context are you using that in the PostgreSQL sense where a single server can support multiple databases (in the same way that a database can support multiple tables etc.), or do you have e.g. pooling software interposed which splits the connections? It's a while since I've had to drill down, but does the server's logging tell you anything interesting about what's going on? I've got a Postgres server with multiple (Postgres-sense) databases here, but I'd have to make the connection over the LAN (i.e. not 127.0.0.1) and would /very/ much prefer having a complete compilable program to work with rather than having to work from snippets. By and large, everything I've done to date has kept databases strictly separate as an important way of isolating clients from each other. I've /considered/ programs that looked at multiple databases (e.g. to look for boilerplate that's been updated for one customer but not for others) but never got around to it. MarkMLl ---------------------------------------------------------------------- martinrame · 2022-11-09 17:27 Hi Mark, the database server (cluster in PostgreSql terminology) runs on the same server, and has two databases. My program establishes two connections, one for each database, pointing to 127.0.0.1:5432 on the same server. I'll take a look at the server logs to see what's happening there. ---------------------------------------------------------------------- martinrame · 2022-11-09 17:29 Every time a my client disconnects, this message is logged in the database logs: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i LOG:  could not receive data from client: Connection reset by peer ---------------------------------------------------------------------- MarkMLl · 2022-11-09 17:33 I've found the server logs to be enormously helpful and- from memory- think it was possible to get them to keep a blow-by-blow account of exactly what was going on. In extremis you can also put the client on a separate system and interpose Wireshark etc. Noting your slightly later message: it might be necessary to step through what's happening on the client with a debugger and see exactly when that message appears on the server. This is a wild guess, but it might be that the server is expecting to only have one open connection to a client program, and for both database access to be passing through that. MarkMLl ---------------------------------------------------------------------- Zvoni · 2022-11-09 17:40 The only thing i noticed: Since when is a constructor/destructor a „Procedure“? ---------------------------------------------------------------------- martinrame · 2022-11-09 17:42 They are not real constructor/destructor, but events, and events are always procedure of object. ---------------------------------------------------------------------- Zvoni · 2022-11-09 17:47 Quote from: martinrame on November 09, 2022, 06:42:12 pmThey are not real constructor/destructor, but events, and events al always procedure of object. Ok, but how do you expect in your Destroy-Event that „inherited“ should work? If i understood it correctly, your „Free“ in finalization calls the destructor, where (probably) you raise the destroy-event. How do you expect code to be executed, when the destructor is called in finalization? ---------------------------------------------------------------------- martinrame · 2022-11-09 17:55 Yes, the inherited isn't necessary, I can delete it. But that doesn't fixes the issue. ---------------------------------------------------------------------- Zvoni · 2022-11-09 18:25 Quote from: martinrame on November 09, 2022, 06:55:34 pmYes, the inherited isn't necessary, I can delete it. But that doesn't fixes the issue. At a guess? In your destroy-event you only close the connection but don‘t free it afterwards. But i admit, i don‘t know if finalization frees any other objects of the module. Have you tried heaptrc to see if there is a memory-leak? Or explicitly free your connections in your event.