silvioprog / brookframework

Microframework which helps to develop web Pascal applications.
https://github.com/risoflora/brookframework
GNU Lesser General Public License v3.0
170 stars 37 forks source link

How am I supposed to free worker thread in brook daemon? #159

Closed Al-Muhandis closed 5 years ago

Al-Muhandis commented 6 years ago

How am I supposed to stop/free worker thread in brook http daemon app? Earlier when I did just brook HTTP server, everything worked fine. The worker/background thread started and stopped in the Initialization and finalization sections of the unit. I wanted to remake the server to work as a Debian daemon, but it does not normally close.

# service iamprd status
● iamprd.service - MyServer server
   Loaded: loaded (/lib/systemd/system/iamprd.service; disabled)
   Active: failed (Result: signal) since Fri 2018-09-28 17:40:09 +04; 5s ago
  Process: 659 ExecStart=/var/www/slymn/data/www/example.ru/cgi-bin/iamprd -r (code=killed, signal=KI       LL)
 Main PID: 659 (code=killed, signal=KILL)

Sep 28 17:31:23 example.ru systemd[1]: Started MyServer server.
Sep 28 17:31:23 example.ru iamprd[659]: [Info] Daemon Brook daemon current status: Start Pending
Sep 28 17:31:23 example.ru iamprd[659]: [Info] Daemon Brook daemon current status: Running
Sep 28 17:39:44 example.ru systemd[1]: Stopping MyServer server...
Sep 28 17:39:44 example.ru iamprd[659]: [Info] Daemon Brook daemon current status: Stop Pending
Sep 28 17:39:44 example.ru iamprd[659]: [Info] Daemon Brook daemon current status: Stopped
Sep 28 17:40:09 example.ru systemd[1]: iamprd.service stop-sigterm timed out. Killing.
Sep 28 17:40:09 example.ru systemd[1]: iamprd.service: main process exited, code=killed, stat...ILL
Sep 28 17:40:09 example.ru systemd[1]: Stopped MyServer server.
Sep 28 17:40:09 example.ru systemd[1]: Unit iamprd.service entered failed state.
Hint: Some lines were ellipsized, use -l to show in full.

My guess is to stop and free the thread of creation and destruction of the daemon. But how? The standard freepascal TDaemon has OnStart and OnStop events. Have TBrookHTTPDaemon such event no. What am I supposed to do?

Al-Muhandis commented 6 years ago

My problem seems to be that I dont know how to access the brook http daemon's start and stop events within which I would be able to create and stop [worker] threads

Al-Muhandis commented 6 years ago

So, I did not come up with a better solution than to make a clone of the brookfclhttpdaemonbroker.pas unit, adding my custom code ((

{ TBrookHttpDaemon }

function TBrookHttpDaemon.Start: Boolean;
begin
  Result := inherited Start;
  FThread := TBrookDaemonThread.Create;
  FThread.Start;

  //  My code
  FWorkerThread:=TWorkerThread.Create;
  FWorkerThread.FreeOnTerminate:=False;
  FWorkerThread.Start;

end;

function TBrookHttpDaemon.Stop: Boolean;
begin
  Result := inherited Stop;
  FThread.Terminate;

  // My code
    FWorkerThread.Terminate;
    RTLeventSetEvent(FWorkerThread.TerminateEvent);

end;
silvioprog commented 6 years ago

@Al-Muhandis awesome. What happens if you call FWorkerThread.WaitFor; instead of RTLeventSetEvent(FWorkerThread.TerminateEvent);?

Al-Muhandis commented 6 years ago

This code (RTLeventSetEvent(FWorkerThread.TerminateEvent);) will serve me for the interruption of delays in the WorkerThread:

  RTLeventWaitFor(FTerminateEvent, Delay); // timeout in milliseconds for thread sleeping
  if Terminated then exit;

I tried adding a WaitFor:

function TBrookHttpDaemon.Stop: Boolean;
begin
  Result := inherited Stop;
  FThread.Terminate;

  // My code
  FWorkerThread.Terminate;
  RTLeventSetEvent(FWorkerThread.TerminateEvent);
  FWorkerThread.WaitFor;
  FWorkerThread.Free;
end; 

In this case just stop command in SSH terminal expects a little more. In both cases, the service Manager no longer forces the daemon to kill. But unfortunately there is a new error:

Sep 29 10:24:49 example.ru systemd[1]: Starting MyServer server...
Sep 29 10:24:49 example.ru systemd[1]: Started MyServer server.
Sep 29 10:24:49 example.ru iamprd[7914]: [Info] Daemon Brook daemon current status: Start Pending
Sep 29 10:24:49 example.ru iamprd[7914]: [Info] Daemon Brook daemon current status: Running
Sep 29 11:41:42 example.ru iamprd[7914]: [Info] Daemon Brook daemon current status: Stop Pending
Sep 29 11:41:42 example.ru iamprd[7914]: [Info] Daemon Brook daemon current status: Stopped
Sep 29 11:41:42 example.ru iamprd[7914]: [Info] Failed to start daemon BrookHttpDaemon : Access violation
Sep 29 11:41:42 example.ru systemd[1]: Stopping MyServer server...
Sep 29 11:41:47 example.ru iamprd[7914]: Error in my_thread_global_end(): 1 threads didn't exit
Sep 29 11:41:47 example.ru systemd[1]: Stopped MyServer server.

Can you tell me what could be wrong? Thank you very much for your feedback!

silvioprog commented 5 years ago

Hi @Al-Muhandis , did you solved this problem?

Al-Muhandis commented 5 years ago

Error has remained. I have a suspicion that any worker thread inside the daemon app should run through the functionality of a separate TDaemonDef class inside the application. I did not check it, because the error does not bother much. It appears only when the service is stopped and the Linux system solves it. I take this as a warning, so don't worry and you can close the topic. If suddenly I can find the solution in the future I update my here. Thank you

silvioprog commented 5 years ago

It seems the problem is related to the user application. Anyway, I have a suggestion, please provide a small example that I can reproduce the problem, so I'll try a deep debug and find the problem.

Al-Muhandis commented 5 years ago

Well, I'll try to make a little example later. Thank you

Al-Muhandis commented 5 years ago

You were right! I tried a stripped-down little example and saw that there was no problem with it. During the study, I figured out that the problem was with the use of TdSQLdbConnector (MySQL driver). I used one connection in a multithreaded connection. :( In the new version, I started using a separate MySQL connection for each thread (TBRookAction, Worker thread) and everything is fine now. Thank you!