Recent

Author Topic: Trying to figure out LazDaemon but facing obstacles  (Read 529 times)

r.lukasiak

  • Full Member
  • ***
  • Posts: 167
Trying to figure out LazDaemon but facing obstacles
« on: September 21, 2023, 01:49:43 am »
Hi everyone!
I'm trying to create a daemon/service. I'm following this link https://wiki.freepascal.org/Daemons_and_Services#Daemons_have_no_Access_to_Network-_and_Cloud_Drives_.28Onedrive.2C_Dropbox.29.
First I went the OnlyCode way, I just copy-pasted the code and I ran into:
Code: Pascal  [Select][+][-]
  1. function TDaemon1.Install: boolean;
  2.  
  3.   var
  4.     FilePath: string;
  5.  
  6.   begin
  7.     Result := False;
  8.     {$IFDEF WINDOWS}
  9.     Result := inherited Install;
  10.     {$ELSE}
  11.       {$IFDEF UNIX}
  12.       FilePath := GetSystemdControlFilePath(Self.Definition.Name);
  13.       LogToFile(Format('TDaemon1: installing control file: %s',[FilePath]));
  14.       Result := CreateSystemdControlFile(self, FilePath);  // <----------------------- I'm getting an error here
  15.       if not Result then
  16.         LogToFile('TDaemon1: Error creating systemd control file: ' + FilePath);
  17.       {$ENDIF}
  18.     {$ENDIF}
  19.     LogToFile(Format('TDaemon1: service %s installed: %s', [self.Definition.Name, BoolToStr(Result, 'ok', 'failure')]));
  20.   end;
  21.  
I get:
Quote
kdaemon.lpr(145,46) Error: Incompatible type for arg no. 1: Got "TDaemon1", expected "TDaemon"

I commented it out and I managed to run the daemon. As expected, running my app with -i failed (as it's commented out), -u was OK and -r ran as needed, I checked the given PID and it was really running.

The I took the other approach. I created a new project "Daemon (service) application". First I played with OnStart / OnStop events, adding some simple Writeln, I ran it and it worked, fired with -r gave expected output and the same when I killed the process.
But then I kept following the tutorial and added the DataModuleStart and DataModuleStops procedures, this resulted in:
Quote
kdaemonunit.pas(43,3) Error: Identifier not found "FDaemonWorkerThread"
and indeed, the tutorial doesn't mention any var, whatsoever so I peeked on the OnlyCode version and added some uses and declared FDaemonWorkerThread

It compiles but when I run it, I get
Quote
$ ./KDaemon -i
An unhandled exception occurred at $00000000004284F4:
EDaemon: Not changing daemon mapper class TKDaemonMapper with TTestDaemonMapper: Only 1 mapper allowed.
  $00000000004284F4
  $00000000004283D7
  $00000000004F2999  DAEMONMAPPERUNIT_$$_init$,  line 40 of daemonmapperunit.pas
  $00000000004174AC

I get the same either I use any parameter or not.

Complete code:
Code: Pascal  [Select][+][-]
  1. unit KDaemonUnit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, DaemonApp, lazdaemonapp, daemonmapperunit, DaemonUnit,
  9.   DaemonWorkerThread;
  10.  
  11. type
  12.  
  13.   { TKDaemon }
  14.  
  15.   TKDaemon = class(TDaemon)
  16.     procedure DataModuleStart(Sender: TCustomDaemon; var OK: Boolean);
  17.     procedure DataModuleStop(Sender: TCustomDaemon; var OK: Boolean);
  18.   private
  19.     FDaemonWorkerThread: TDaemonWorkerThread;
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   KDaemon: TKDaemon;
  27.  
  28. implementation
  29.  
  30. procedure RegisterDaemon;
  31. begin
  32.   RegisterDaemonClass(TKDaemon)
  33. end;
  34.  
  35. {$R *.lfm}
  36.  
  37. { TKDaemon }
  38.  
  39. procedure TKDaemon.DataModuleStart(Sender: TCustomDaemon; var OK: Boolean);
  40. begin
  41.   Writeln(Format('Daemon received start signal, PID:%d', [GetProcessID]));
  42.   // Create a suspended worker thread - see DaemonWorkerThread unit
  43.   FDaemonWorkerThread := TDaemonWorkerThread.Create;
  44.   // Parametrize it
  45.   FDaemonWorkerThread.FreeOnTerminate := False;
  46.   // Start the worker
  47.   FDaemonWorkerThread.Start;
  48.   OK := True;
  49. end;
  50.  
  51. procedure TKDaemon.DataModuleStop(Sender: TCustomDaemon; var OK: Boolean);
  52. begin
  53.   Writeln('Daemon received stop signal');
  54.   // stop and terminate the worker
  55.   if assigned(FDaemonWorkerThread) then
  56.   begin
  57.     FDaemonWorkerThread.Terminate;
  58.     // Wait for the thread to terminate.
  59.     FDaemonWorkerThread.WaitFor;
  60.     FreeAndNil(FDaemonWorkerThread);
  61.   end;
  62.   Writeln('Daemon stopped');
  63.   OK := True;
  64. end;
  65.  
  66.  
  67. initialization
  68.   RegisterDaemon;
  69. end.
  70.  

At this point I have absolutely no clue what I did wrong. Any hint?
« Last Edit: September 21, 2023, 06:06:43 am by r.lukasiak »

 

TinyPortal © 2005-2018