You are not logged in.
The function in the SOA is defined as follows:
function server.functiontotest: string;
var
g: Integer;
ResultStr: string;
begin
g := 0;
ResultStr := '';
while g < 40000 do
begin
ResultStr := ResultStr + IntToStr(g);
Inc(g); // Increment g
end;
Result := ResultStr;
end;
The function takes time to return a result. When I call the function with 2 or 3 clients, it returns the result successfully. However, when I call it more than 4 times, I always get a timeout error. Additionally, I am using sicShared for the SOA. Even when I try changing to sicPerThread, I still encounter the same problem.
Offline
Which compiler?
Which OS?
How many CPU cores?
My guess is that you only have 4 processing threads (i.e. 4 threads in your HTTP connection), so you get a timeout once all threads are busy.
For such huge process, you need a dedicated thread. Do not pollute the HTTP threads with slow process.
This is why we created the interface based service callbacks, to notify the client once a process is finished, without blocking the HTTP threads.
Offline
I'am working with Windows 10 in virtual machine using Delphi 12.0 Athens / C++Builder 12.0 Athens, product version of 23.0.
CPU : Common KVM processor: 2.10 GHz with 2 cores , 2 sockets and mormot 2.2
Last edited by salah eddine frigini (2024-10-24 15:47:21)
Offline
I am using sicPerThread with a thread pool size of 32 and useHttpSocket. Each time I call the function, the server uses one thread to execute it. I called the function four times, and I have 32 threads in the pool. I don't know why I am experiencing a timeout.
// creation of the server
TSQLRestServerDB.Create(HttpPort, [tsimpleserver], '+', useHttpSocket);//32 in the thread pool by default
constructor tsimpleserver.Create(aModel: TORMModel; aDBFILENAME: TFileName);
begin
inherited Create(aModel, aDBFILENAME);
ServiceDefine(TemployeeService, [IEmpService], sicPerThread);
end;
Offline
When I change the number of iterations in the function from 40,000 to 30,000, I can call the function 6 times concurrently. However, when I try to call it 7 times concurrently, they all give me a timeout.
Offline
Theoretically, the execution speed of your service code should not be very slow, and it should not hinder or block the processing thread of the HTTP request. Moreover, even if it does get blocked, for example, you could replace the service code with Sleep(10000), but by default, the thread pool handling requests has 32 work-threads, so it shouldn't block the client's service calls. It's really strange. Could you provide some logs to see what the server-side WebSocket is doing?
Offline
//My server initiates 32 threads after it calls root/timestamp and root/EmpService._contract_.
//Then, it calls the function TestThread.
Interface Post: root/EmpService.TestThread = 200 out, 20 B in, 28.67 s
mormot.rest.server.TrestServerRoutingRest(03fe3880) {"result":["30000"]}
28.678.115
Interface Post: root/EmpService.TestThread = 200 out, 20 B in, 32.76 s
mormot.rest.server.TrestServerRoutingRest(03fe3580) {"result":["30000"]}
32.769.536
Interface Post: root/EmpService.TestThread = 200 out, 20 B in, 32.13 s
mormot.rest.server.TrestServerRoutingRest(03fe3b80) {"result":["30000"]}
32.134.841
Interface Post: root/EmpService.TestThread = 200 out, 20 B in, 32.20 s
mormot.rest.server.TrestServerRoutingRest(03fe3a00) {"result":["30000"]}
32.208.935
Interface Post: root/EmpService.TestThread = 200 out, 20 B in, 31.77 s
mormot.rest.server.TrestServerRoutingRest(03fe3e80) {"result":["30000"]}
32.780.074
Interface Post: root/EmpService.TestThread = 200 out, 20 B in, 33.57 s
mormot.rest.server.TrestServerRoutingRest(03fe3d00) {"result":["30000"]}
32.582.705
trace unit6.TsimpleServer(039b86c0) End current thread (THttpServerResp) Thread ID=1390 'Httpsrv 11111 root ThttpsrvResp' thread count = 6
trace unit6.TsimpleServer(039b86c0) End current thread (THttpServerResp) Thread ID=02a8 'Httpsrv 11111 root ThttpsrvResp' thread count = 5
trace unit6.TsimpleServer(039b86c0) End current thread (THttpServerResp) Thread ID=88 'Httpsrv 11111 root ThttpsrvResp' thread count = 4
trace unit6.TsimpleServer(039b86c0) End current thread (THttpServerResp) Thread ID=13a4 'Httpsrv 11111 root ThttpsrvResp' thread count = 3
trace unit6.TsimpleServer(039b86c0) End current thread (THttpServerResp) Thread ID=1de4 'Httpsrv 11111 root ThttpsrvResp' thread count = 2
trace unit6.TsimpleServer(039b86c0) End current thread (THttpServerResp) Thread ID=1de4 'Httpsrv 11111 root ThttpsrvResp' thread count = 1
The server always returns a result, but in the console of my test, I get a timeout error if I call the function more than six times. If I call it fewer than six times, I receive the result in the test console.
I can also call the function concurrently more than six times and receive the result in the test console, but I have to increase the number of iterations from 30,000 to less than 20,000.
this is the erreur in the test console :
EXC EInterfaceFactory {Message: "TInterfacedObjectFakeClient.FakeCall(IEmpService.TestThread) failed: 'URI root/IEmpService.TestThread [] return status 'Request Timeout' (408)"} [main] at 7a526d
Offline
Log shows you have 6 working threads, not 32! Execution time is >30sec, default timeout is 10sec if I remember.
Last edited by ttomas (2024-10-28 12:02:36)
Offline
"but in the console of my test, I get a timeout error if I call the function more than six times
What does this sentence mean?
Is there any difference between the so-called "console of my test" and "///then, it calls the function TestThread"?
In "console of my test", did you also initiate the test using thread concurrency?
My suggestions are:
Server Side:
1. Output the `YourRestHttpServer.HttpServer.HttpQueueLength` property
2. Output the `TWebSocketServerRest(YourRestHttpServer.HttpServer).ThreadPool.WorkThreadCount` property (or using THttpServer(YourRestHttpServer.HttpServer).ThreadPool....)
Client Side:
1. Set global variable `HTTP_DEFAULT_RECEIVETIMEOUT := 120000`
2. Set `YourRestHttpClientWebsockets.RetryOnceOnTimeout := true`
Offline