#1 2017-12-24 18:21:08

ertank
Member
Registered: 2016-03-16
Posts: 163

Proper code to run service application

Hello,

I am using Lazarus 1.8.1 (1.8 fixes branch), fpc 3.1.1 (trunk) on a Raspberry Pi 3 device running Raspbian Stretch. mORMot commit version is 1.18.3688

I am basically a Windows programmer and I know no technical details as to linux daemons. I recently completed my interface based service on Raspberry Pi 3 device. I have following code in my LPR file:

var
  Application: TMyInterfaceServer;
begin
  Application := TMyInterfaceServer.Create(nil);
  Application.Run();
  Application.RunServer();
  while not Application.Terminated do Sleep(1000);
  Application.Free();
end.

Above code results in instant shutdown of the application as if it is terminated. Relevant log lines are:

/home/pi/interfaceserver 0.0.0.0 (2017-12-24 20:48:11)
Host=raspberrypi User=root CPU=0 OS=Linux-4.9.59-v7+#1047-SMP-Sun-Oct-29-12:19:23-GMT-2017 Wow64=0 Freq=1000000000
TSynLog 1.18.3688 FTS3 2017-12-24T17:50:06

20171224 17500617  +    mORMotHttpServer.TSQLHttpServer(76A45380).Create useBidirSocket (secNone) on port 8888
20171224 17500617  -    00.000.172
20171224 17500618 http  mORMotHttpServer.TSQLHttpServer(76A45380) {"TWebSocketServerRest(76A645C0)":{"ServerConnectionCount":0,"ServerKeepAliveTimeOut":3000,"TCPPrefix":"","ThreadPool":{"TSynThreadPoolTHttpServer(76CACB60)":{"HeaderErrors":0,"HeaderProcessed":0,"BodyProcessed":0,"BodyOwnThreads":0,"RunningThreads":2}},"ThreadPoolContentionCount":0,"ThreadPoolContentionAbortCount":0,"APIVersion":"Synopse CrossPlatform Socket Layer.514","ServerName":"mORMot (Linux)","ProcessName":"root "}} initialized for root
20171224 17500618 info  SetThreadName 75F53470=TSQLHttpServer 8888/root TWebSocketServerRest
20171224 17500618 trace mORMot.TSQLRestServerFullMemory(76A34D40) BeginCurrentThread(TWebSocketServerRest) root=root ThreadID=75F53470 ThreadCount=1
20171224 17500618  +    mORMotHttpServer.TSQLHttpServer(76A45380).
20171224 17500618  -    00.000.124
20171224 17500618 http  mORMotHttpServer.TSQLHttpServer(76A45380) {"TWebSocketServerRest(76A645C0)":{"ServerConnectionCount":0,"ServerKeepAliveTimeOut":3000,"TCPPrefix":"","ThreadPool":{"TSynThreadPoolTHttpServer(76CACB60)":{"HeaderErrors":0,"HeaderProcessed":0,"BodyProcessed":0,"BodyOwnThreads":0,"RunningThreads":2}},"ThreadPoolContentionCount":0,"ThreadPoolContentionAbortCount":0,"APIVersion":"Synopse CrossPlatform Socket Layer.514","ServerName":"mORMot (Linux)","ProcessName":"root "}} finalized for 1 server
20171224 17500618  +    mORMotHttpServer.TSQLHttpServer(76A45380).Shutdown(true)
20171224 17500618  -    00.000.078
20171224 17500650 trace mORMot.TSQLRestServerFullMemory(76A34D40) EndCurrentThread(TWebSocketServerRest) ThreadID=75F53470 ThreadCount=0
20171224 17500650  +    mORMot.TSQLRestServerFullMemory(76A34D40).Shutdown CurrentRequestCount=0 File=
20171224 17500650  -    00.005.133
20171224 17500650 info  mORMot.TSQLRestStorageInMemory(76904020) TSQLRestStorageInMemory.Destroy
20171224 17500650 info  mORMot.TSQLRestStorageInMemory(769040F0) TSQLRestStorageInMemory.Destroy
20171224 17500650 info  mORMot.TSQLRestServerFullMemory(76A34D40) TSQLRestServerFullMemory.Destroy

However, below code keeps the application running:

var
  Application: TMyInterfaceServer;
begin
  Application := TMyInterfaceServer.Create(nil);
  Application.Run();
  Application.RunServer();
  while True do Sleep(1000);  // modified line
  Application.Free;
end.

I am not sure if this should be the way I should keep the application running. I think second code results in a memory leak or something. I cannot be sure because of my lack of linux knowledge.

All suggestions are welcome.

Thanks & regards,
Ertan

Last edited by ertank (2017-12-24 18:22:23)

Offline

#2 2017-12-25 14:52:38

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: Proper code to run service application

What is a TMyInterfaceServer ?

Please use pastebin if you want to show a lot of code.

Offline

#3 2017-12-25 20:59:59

ertank
Member
Registered: 2016-03-16
Posts: 163

Re: Proper code to run service application

It is a TCustomApplication class. I believe I copy paste it long time ago from some demo application.

  TMyInterfaceServer = class(TCustomApplication)
  protected
    procedure DoRun; override;
  private
    LogDir: string;
    procedure RunServer();
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
    procedure WriteHelp; virtual;
  end;

Sorry about long code paste. I shall find a working pastebin alternative. It cannot be reached as I have governmental internet ban for some web sites.

Offline

#4 2017-12-26 08:54:27

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: Proper code to run service application

So it is more a TCustomApplication use problem: it just don't wait for anything.

Did you try to put a sleep() before checking for Terminated?

repeat Sleep(1000) until Application.Terminated;

Offline

#5 2017-12-26 10:15:32

ertank
Member
Registered: 2016-03-16
Posts: 163

Re: Proper code to run service application

When I try suggested code, result is same. Application exit immediately. Probably this is some kind of a bug in TCustomApplication class. I will see if Lazarus forum will be of any help.

Thanks.

Offline

#6 2017-12-26 11:17:39

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: Proper code to run service application

Take a look at mORMotServices.pas - there is a daemon abstract class there.

Offline

Board footer

Powered by FluxBB