We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hi. THorse freezes when closing the application. Here is full solution.
unit Horse.Provider.FPC.Daemon; {$IF DEFINED(FPC)} {$MODE DELPHI}{$H+} {$ENDIF} interface {$IF DEFINED(HORSE_DAEMON) AND DEFINED(FPC)} uses SysUtils, Classes, httpdefs, fpHTTP, fphttpserver, Horse.Request, Horse.Response, Horse.Core, Horse.Provider.Abstract, Horse.Constants, Horse.Proc, Horse.Commons; type { THTTPServerThread } THTTPServerThread = class(TThread) private FServer: TFPHTTPServer; FHorse: THorseCore; procedure OnIdle(Sender: TObject); public constructor Create(const AHost: string; const APort, AListenQueue: Integer); destructor Destroy; override; procedure Execute; override; procedure OnRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse); end; THorseProvider = class(THorseProviderAbstract) private class var FPort: Integer; class var FHost: string; class var FRunning: Boolean; class var FListenQueue: Integer; class var FHTTPServerThread: THTTPServerThread; class procedure SetListenQueue(const AValue: Integer); static; class procedure SetPort(const AValue: Integer); static; class procedure SetHost(const AValue: string); static; class function GetListenQueue: Integer; static; class function GetPort: Integer; static; class function GetDefaultPort: Integer; static; class function GetDefaultHost: string; static; class function GetHost: string; static; class procedure InternalListen; virtual; class procedure InternalStopListen; virtual; public class property Host: string read GetHost write SetHost; class property Port: Integer read GetPort write SetPort; class property ListenQueue: Integer read GetListenQueue write SetListenQueue; class procedure StopListen; override; class procedure Listen; overload; override; class procedure Listen(const APort: Integer; const AHost: string = '0.0.0.0'; const ACallbackListen: TProc = nil; const ACallbackStopListen: TProc = nil); reintroduce; overload; static; class procedure Listen(const APort: Integer; const ACallbackListen: TProc; const ACallbackStopListen: TProc = nil); reintroduce; overload; static; class procedure Listen(const AHost: string; const ACallbackListen: TProc = nil; const ACallbackStopListen: TProc = nil); reintroduce; overload; static; class procedure Listen(const ACallbackListen: TProc; const ACallbackStopListen: TProc = nil); reintroduce; overload; static; class destructor UnInitialize; class function IsRunning: Boolean; end; {$ENDIF} implementation {$IF DEFINED(HORSE_DAEMON) AND DEFINED(FPC)} uses Horse.WebModule, Horse.Exception.Interrupted; { THTTPServerThread } procedure THTTPServerThread.OnRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse); var LRequest: THorseRequest; LResponse: THorseResponse; begin LRequest := THorseRequest.Create(ARequest); try LResponse := THorseResponse.Create(AResponse); try try if not FHorse.Routes.Execute(LRequest, LResponse) then begin AResponse.Content := 'Not Found'; AResponse.Code := THTTPStatus.NotFound.ToInteger; end; except on E: Exception do if not E.InheritsFrom(EHorseCallbackInterrupted) then raise; end; finally if LRequest.Body<TObject> = LResponse.Content then LResponse.Content(nil); LRequest.Free; end; finally LResponse.Free; end; end; procedure THTTPServerThread.OnIdle(Sender: TObject); begin if Terminated then FServer.Active := False; end; constructor THTTPServerThread.Create(const AHost: string; const APort, AListenQueue: Integer); begin inherited Create(True); FreeOnTerminate := False; FServer := TFPHTTPServer.Create(nil); FServer.AcceptIdleTimeout := 1000; FServer.HostName := AHost; FServer.Port := APort; FServer.ThreadMode := tmThread; FServer.QueueSize := AListenQueue; FServer.OnAcceptIdle := OnIdle; FServer.OnRequest := OnRequest; FHorse := THorseCore.GetInstance; end; destructor THTTPServerThread.Destroy; begin FServer.Free; inherited Destroy; end; procedure THTTPServerThread.Execute; begin FServer.Active := True; end; { THorseProvider } class function THorseProvider.IsRunning: Boolean; begin Result := FRunning; end; class procedure THorseProvider.StopListen; begin InternalStopListen; end; class function THorseProvider.GetDefaultHost: string; begin Result := DEFAULT_HOST; end; class function THorseProvider.GetDefaultPort: Integer; begin Result := DEFAULT_PORT; end; class function THorseProvider.GetHost: string; begin Result := FHost; end; class function THorseProvider.GetListenQueue: Integer; begin Result := FListenQueue; end; class function THorseProvider.GetPort: Integer; begin Result := FPort; end; class procedure THorseProvider.InternalListen; begin if not IsRunning then begin if FPort <= 0 then FPort := GetDefaultPort; if FHost.IsEmpty then FHost := GetDefaultHost; if FListenQueue = 0 then FListenQueue := 15; FHTTPServerThread := THTTPServerThread.Create(FHost, FPort, FListenQueue); FHTTPServerThread.Start; FRunning := True; DoOnListen; end; end; class procedure THorseProvider.Listen; begin InternalListen; end; class procedure THorseProvider.Listen(const APort: Integer; const AHost: string; const ACallbackListen, ACallbackStopListen: TProc); begin SetPort(APort); SetHost(AHost); SetOnListen(ACallbackListen); SetOnStopListen(ACallbackStopListen); InternalListen; end; class procedure THorseProvider.Listen(const AHost: string; const ACallbackListen, ACallbackStopListen: TProc); begin Listen(FPort, AHost, ACallbackListen, ACallbackStopListen); end; class procedure THorseProvider.Listen(const ACallbackListen, ACallbackStopListen: TProc); begin Listen(FPort, FHost, ACallbackListen, ACallbackStopListen); end; class procedure THorseProvider.Listen(const APort: Integer; const ACallbackListen, ACallbackStopListen: TProc); begin Listen(APort, FHost, ACallbackListen, ACallbackStopListen); end; class procedure THorseProvider.SetHost(const AValue: string); begin FHost := AValue; end; class procedure THorseProvider.SetListenQueue(const AValue: Integer); begin FListenQueue := AValue; end; class procedure THorseProvider.SetPort(const AValue: Integer); begin FPort := AValue; end; class destructor THorseProvider.UnInitialize; begin InternalStopListen; end; class procedure THorseProvider.InternalStopListen; begin if IsRunning then begin FHTTPServerThread.Terminate; FHTTPServerThread.WaitFor; FHTTPServerThread.Free; DoOnStopListen; FRunning := False; end; end; {$ENDIF} end.
The text was updated successfully, but these errors were encountered:
Hello, would you like to submit a pull request with the tweak?
Sorry, something went wrong.
Yes, please.
@sf-spb , Will you send us a pull request?
No branches or pull requests
Hi. THorse freezes when closing the application. Here is full solution.
The text was updated successfully, but these errors were encountered: