#1 2016-05-27 16:04:06

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Request for a HTTP server workflow changes

@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

#2 2016-05-27 22:19:53

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: Request for a HTTP server workflow changes

You have such events at TSqlRestServer.URI level AFAIR...

Offline

#3 2016-05-30 07:41:20

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: Request for a HTTP server workflow changes

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

#4 2016-06-10 16:50:29

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: Request for a HTTP server workflow changes

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

#5 2016-06-10 21:13:10

oz
Member
Registered: 2015-09-02
Posts: 98

Re: Request for a HTTP server workflow changes

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

#6 2018-02-10 14:15:08

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: Request for a HTTP server workflow changes

@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

#7 2018-02-26 12:30:05

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: Request for a HTTP server workflow changes

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

#8 2018-02-26 13:46:13

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,669
Website

Re: Request for a HTTP server workflow changes

Perhaps it is even better with https://synopse.info/fossil/info/f72d02b490

Offline

#9 2018-02-26 14:37:04

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: Request for a HTTP server workflow changes

Yes. In my code I set OnBeforeRequest handler before call to Clone() so miss this issue

Offline

Board footer

Powered by FluxBB