THTTPServer в потоке Daemona

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
GreyCrazyWolf
новенький
Сообщения: 12
Зарегистрирован: 02.03.2023 14:23:57

THTTPServer в потоке Daemona

Сообщение GreyCrazyWolf »

Добрейшего времени суток, пишу демон, который должен стартовать HTTP сервер, все работает за исключением одного - корректного завершения работы сервера

Сам сервер запускается в Execute так

Код: Выделить всё

      LogToFile('Running http server.....');

      FHttpServer := TFPHttpServer.Create(nil);
      FHttpServer.Port := CurrentSettings.AppPort; //9080;
      FHttpServer.UseSSL := true;
      FHttpServer.OnRequest:= @DoHandleRequest;

      FHttpServer.CertificateData.Certificate.FileName := 'certificate.crt';
      FHttpServer.CertificateData.PrivateKey.FileName := 'privateKey.key';
      FHttpServer.Threaded := true;

      LogToFile('Running http server (Active:= true) .....');

      repeat //  сделано для проверки

            FHttpServer.Active:= true; // это запускается и работает
            LogToFile('Http server is run.'); // сюда уже не доходит

      until Terminated; // сюда уже не доходит

      LogToFile('Exit from repeat ');
Остановка делается отдельной процедурой

Код: Выделить всё

procedure TCliSvr.StopServer;
begin

  LogToFile('Stopping HTTP server...');

  if Assigned(FHttpServer) then
    begin
      FHttpServer.Active:=False;
      //FreeAndNil(FHttpServer);    // сначала было так, потом перенес в деструктор класса
      LogToFile('FreeAndNil(FHttpServer) ');
    end;

  LogToFile('Done StopServer');

end;  
деструктор класса

Код: Выделить всё

begin
  // Nothing to do here, just for logging
  FHttpServer.Free;
  LogToFile('Daemon worker thread destroyed');
  inherited Destroy;
end;  
Запуск и остановка демона фактически взяты в вики

Код: Выделить всё

procedure TDaemonCliSvr.DataModuleStart(Sender: TCustomDaemon; var OK: Boolean);
begin
  LogToFile(Format('Daemon received start signal, PID:%d', [GetProcessID]));
  // Create a suspended worker thread - see DaemonWorkerThread unit
  FCliSvr := TCliSvr.Create;
  // Parametrize it
  FCliSvr.FreeOnTerminate := False;
  // Start the worker
  FCliSvr.Start;
end;

procedure TDaemonCliSvr.DataModuleStop(Sender: TCustomDaemon; var OK: Boolean);
begin

  try

  LogToFile('Daemon received stop signal');
  // stop and terminate the worker
  if assigned(FCliSvr) then
  begin
    FCliSvr.Terminate;
    sleep(100);                                // добавлено от безыходности :))
    FCliSvr.StopServer;
    sleep(100);                                // добавлено от безыходности :))
    // Wait for the thread to terminate.
    LogToFile('prepare FCliSvr.WaitFor'); // на этом виснет при первом нажатии Ctrl+C
    FCliSvr.WaitFor;
    LogToFile('prepare  FreeAndNil(FCliSvr)');
    FreeAndNil(FCliSvr);                          // если закомментировать  FCliGalSvrThread.WaitFor' то завис тут
  end;
  LogToFile('Daemon stopped');                              // сюда приходит после двух  трех Ctrl+C
  Halt;
  OK := True;

  except

    on E: Exception do begin
      writeln('Exception: HasError '+E.ToString);
      LogToFile('Exception: HasError '+E.ToString);
    end;

  end;   
Для отладки пробую запускать приложение под sudo c ключом -r (пример с закомментированным FCliSvr.WaitFor;)

Код: Выделить всё

..../Cli/ServerService$ sudo ./CliSrv -r
13:06:09 Daemon received start signal, PID:9975
13:06:09 Daemon worker thread created
13:06:09 Running http server.....
13:06:09 Running http server (Active:= true) .....
Try connect to: database
Connection is established
^C13:06:27 Daemon received stop signal   // первое нажатие Ctrl+C
13:06:27 Stopping HTTP server...
13:06:27 FreeAndNil(FHttpServer) 
13:06:27 FreeAndNil(FilesSaver)
13:06:27 Done StopServer
13:06:28 prepare  FreeAndNil(FCliGalSvrThread)
13:06:28 Daemon worker thread destroyed // ЗАВИСАНИЕ, но судя по логу деструктор отработал
^C13:06:51 Daemon received stop signal // второе нажатие Ctrl+C
13:06:51 Daemon stopped
.../Cli/ServerService$
помогите разобраться, как это победить :(
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

// ЗАВИСАНИЕ, но судя по логу деструктор отработал
Нужно лезть в код и прописывать логгирование каждой строчки проблемных процедур, найти что работает не так, а потом патчить. Если требуется глушить программу два раза, то скорее всего, чего-то в её коде не хватает, надо добавить.
GreyCrazyWolf
новенький
Сообщения: 12
Зарегистрирован: 02.03.2023 14:23:57

Сообщение GreyCrazyWolf »

Сквозняк писал(а):Нужно лезть в код и прописывать логгирование каждой строчки проблемных процедур, найти что работает не так, а потом патчить. Если требуется глушить программу два раза, то скорее всего, чего-то в её коде не хватает, надо добавить.
Штука в том что судя по всему завис происходит на

Код: Выделить всё

inherited Destroy;
причем все что можно уже делается Free
Ответить