CPU Usage After Canceling Connection

Good morning,

I have a problem with my server.

My clients have been accessing the server and after a while the server’s CPU usage has become very high.

I was able to reproduce the problem in the following way. I set up a cURL to run in a loop at the DOS prompt, and if I cancel this loop, the server’s usage increases and becomes very high.

My server code:

  [ROService(__ServiceName)]
  TSispetroWeb = class(TRORemoteDataModule)
    procedure RORemoteDataModuleCreate(Sender: TObject);
    procedure RORemoteDataModuleDestroy(Sender: TObject);
    procedure RORemoteDataModuleGetDispatchInfo(const aTransport: IROTransport;
      const aMessage: IROMessage);
    procedure RORemoteDataModuleActivate(const aClientID: TGUID;
      aSession: TROSession; const aMessage: IROMessage);
  private
    ipCliente : string;
    conexao: TFdConnection;
  public

    [ROServiceMethod]
    [ROCustom('HttpApiPath','getboleto')]
    [ROCustom('HttpApiMethod','GET')]
    function getBoleto([ROCustom('HttpApiQueryParameter','1')] codempresa: Integer;
                       [ROCustom('HttpApiQueryParameter','1')] numlancamento: Integer): Binary;

    [ROServiceMethod]
    [ROCustom('HttpApiPath','getdanfe')]
    [ROCustom('HttpApiMethod','GET')]
    function getDanfe([ROCustom('HttpApiQueryParameter','1')] codempresa: Integer;
                       [ROCustom('HttpApiQueryParameter','1')] sequencial: Integer): Binary;

Curl call

FOR /L %%X IN (0,1,25) DO curl -Z "http://192.168.125.128:8095/getboleto?codempresa=13&numlancamento=14029" -o file1.pdf "http://192.168.125.128:8095/getboleto?codempresa=13&numlancamento=14029" -o file2.pdf

How could I cancel the processing when that connection no longer exists? It seems like it is trying to answer the call.

Hi,

what http server are you using? We have 5 http servers …
Can you create a simple testcase that reproduces issue, pls?


Can you retest this behavior with other http server, pls?

TROHTTPServer

I can quickly change my application from TROHTTPServer to TROIndyHTTPServer.

{$IFDEF SERVIDOR_INDY}
    FRoServerWeb: TRoIndyHttpServer;
    FRoServer: TRoIndyHttpServer;
    FRoServerControl: TRoIndyHttpServer;
{$ELSE}
    FRoServerWeb: TROHttpServer;
    FRoServer: TROHttpServer;
    FRoServerControl: TROHttpServer;
{$ENDIF}

With TROIndyHTTPServer the same situation did not cause any problems…

It seems that the problem is only with TROHTTPServer

When I am using the Indy server, I use the following code.

        var socket: TIdSocketHandle;        
        
        FRoServerWeb.IndyServer.Bindings.Clear;
        socket := FRoServerWeb.IndyServer.Bindings.Add;
        socket.IP := self.FIP;
        socket.Port := self.FPorta;

In httpserver I use this code.

FRoServerWeb := TROHttpServer.Create(nil);
FRoServerWeb.OnManualBindSocket := ServerManualBindSocketWeb;
      
procedure TServerHttp.ServerManualBindSocketWeb(Sender: TObject);
begin
  FRoServerWeb.Server.Socket4.Bind(self.FIP, Self.FPortaSisPetroWeb);
end

Would that be right?

Hi,

I think, better to set BindV4/BindV6 properties too. it may increase understanding the code, like

FRoServerWeb := TROHttpServer.Create(nil);
// FRoServerWeb.BindV4 := True;
// FRoServerWeb.BindV6 := False;
FRoServerWeb.OnManualBindSocket := ServerManualBindSocketWeb;

it is correct.
also you can use something like

procedure TForm12.ROHTTPServer1ManualBindSocket(Sender: TObject);
begin
  TROAsyncHTTPServer(Sender).Socket4.Bind(ip, port);
end;

That was the only difference between Indy and HTTServer.

I made these improvements to the code and nothing.

In Indy it doesn’t increase the CPU but HTTServer does.

Hi,

I can’t reproduce this case with very simple testcase.

Can you update my testcase, pls?
31684.zip (109.7 KB)

RemObjects.rar (115.2 KB)

Good morning, Thank you for the project.

I made a change to it to make it similar to my structure.

I was able to reproduce the problem.

It only started happening after I implemented the code below.

  Result := TROHttpApiResult.Create(HTTP_200_code, id_ContentType_application_pdf,'',false);
  Result.LoadFromFile( 'ORI.PDF' );

Hi,

try to update uROSocketUtils.pas as

function RO_SendBuffer(aSocket: THandle; Buffer: Pointer; Len: Integer): Integer;
...
    until not l_retry;
    if Result = SOCKET_ERROR then Exit; // added

and retest.

Can you reproduce original behavior after this fix?

Logged as bugs://D19542.

bugs://D19542 was closed as fixed.

This change fixed the issue.

1 Like