You are not logged in.
Pages: 1
@AB & community
I need several additional features in HTTP server and I want discuss how to do it in the best way (to not create a dead branch as I did with HTTP API based web sockets)
So, the requirements are:
1) Add a limitation of incoming request size (based on a rules)
The main requirement is to not read entry request body if rule fail. I have a real problem - my users overflow a 100 Mbit channels.
2) Add a ability to execute a long tasks in the same thread pool server currently use
For example server got e request and I absolutely sure (based on the URL & header analysis) it will take some long time (for example I need to go to the slow third party services, then write something to my database and so on).
I can fork a thread for this task, but I should strictly control the amount of resources (database connections, threads, disk I/O) my server use. If can create "another" thread pool for a long tasks, but in this case I need to create a queue and so on.
I investigate how such requirements solved in other architectures - the common way is to answer to client with a "HTTP 202 Accepted" response and continue to execute the task as usual. Then a task compleate we can send a webSocket message, or client can long-pool me - it dose not meter.
My propose is to add three event handler to the THttpServerGeneric: OnAtferHeaderRetrived, OnBeforeProcess & OnAfterProcess and implement a main HTTP servers loop in this way
read headers to a Context: THttpServerRequest
call OnAtferHeaderRetrived(Context); // here I can check content length, pre-check a authentication (in case body crc is not needed or this is a first auth stage), and fill a Out* fields, for example with "200 !STATICFILE"
if Context.OutStatus <> 0 then
SendResponse(Context)
else begin
read request body to Context
call OnBeforeProcess(Context); // here I can decide to return error or a 202
if Context.OutStatus <> 0 then // if I change a status - return a response
SendResponse(Context);
if Context.OutStatus = 0 or Context.OutStatus =202 then begin // run as in current implementation
needToSendAResponse = (Context.OutStatus =202);
Process(Context);
if needToSendAResponse then SendResponse(Context); // send response if we do not send a 202 before
end;
call OnAfterProcess(context); // here I can gather statistics, write some logs to a database (but client not wait for me), and so on
end;
It seems to me it can be implemented without breaking changes for mORMot. At last I clearly understand how to implement it for a THttpApiServer but not sure for other server types...
Any ideas?
Offline
Events TSqlRestServer.OnBeforeURI & TSqlRestServer.OnAfterURI executed inside a URI procedure after all part of HTTP request are retrieved, but I need a event handler what fire after only a headers of HTTP request are retrieved. And on the TSqlRestServer level there is no way to return a HTTP response and continue execution of URI procedure ...
Offline
I'm implement a HTTP server events I'm talking about for the THttpApiServer - see branch HTTPServerEvents.
Having such events we can solve a several things:
1) Limit a upload size as @Eric request here: http://synopse.info/forum/viewtopic.php?id=992
2) Server can answer 202 Accepted to client and continue to run a long-term-job without creating a new threads
3) Request pre- and post- processors can be added, so we can do all the job of @EugeneIlyin TBoilerPlateHttpServer (great work!) in a event handlers instead of descendants
The first two is critical for my application and I can't do what I need without mORMot source modifications.
@AB if you have a time - please, review my code. I will be very happy if it be merged to trunk. If so, we can try to do the same modifications to Socket-based servers
Last edited by mpv (2016-06-10 16:50:55)
Offline
Personally, i'm also very interested in seeing this feature beeing implemented in trunk.
Unfortunately I had no time to give that http.sys based WebSocket server a try, neither to have a look at that fork.
But it really sounds promising imho.
Offline
@ab - I'm already implement a THttpApiServer.OnBeforeRequestProcessed & OnAfterRequesProcessed events.
Actual changes is very small - I just move a peace of code for sending response to SendResponse inner function without any modification and add a several if's.
This feature is critical for me - I need an ability to send "202 accepted" response to client BEFORE actual job on server is done, and after this continue a hard calculation in the thread where HTTP request comes to.
For example I use this to send a request from cron deamon (something like POST /cronJob?jobName=rebuildIndex&async=true ) or to interrupt a JS debugger in the HTTP thread etc.
I create a merge request on GIT. Also I need your help to implement the same for socket based server (just piont me to the place in code where to do it)
Last edited by mpv (2018-02-10 14:16:36)
Offline
Feature merged into trunk mORMot 1.18.4342. My tests (for both http.sys & plain sockets server) is passed.
@AB - thank you very much!
Last edited by mpv (2018-02-26 12:47:47)
Offline
Perhaps it is even better with https://synopse.info/fossil/info/f72d02b490
Offline
Pages: 1