Event-driven handler

Manlio Perillo manlio_perillo at libero.it
Wed Feb 18 21:26:35 MSK 2009


Eugaia ha scritto:
> 
> [...]
>
>> You just have to return NGX_DONE from the handler, and call 
>> ngx_http_finalize_request when done.
> This may be what I need to know.  If I return NGX_DONE, is the request 
> the response then not automatically
> sent to the client?  

Nginx handles response body in chunks.
Each time you call ngx_http_output_filter, your chain buffer is sent to 
Nginx filters and *may* be sent to OS socket buffer.

> In order to do that, you need to call 
> ngx_http_finalize_request. Is that right?
> 

Calling nxg_http_finalize_request simply, as the name suggest, instruct 
Nginx to finalize the current request.

> What about if I want to use filters after my content has been 
> generated?  E.g. gzip.  At the moment, my
> code calls ngx_http_output_filter in my handler and returning the 
> response from that.
> 

See my previous response.
You need to call ngx_http_output_filter as usual, but there are some 
things you have to check:

1) If an error is returned, then you need to call
    ngx_http_finalize_request, with that the error code
2) If NGX_AGAIN is returned, then you need to setup the code
    so that your handler is called again when Nginx know that the socket
    buffer is empty again.

    This is one of the most "complex" parts.
    Again, the source code from mod_wsgi may help
    (although I can not guarantee it is correct).

> Should I instead do something like:
> 
> [my handler]
> - sends request to my output-generating code (which may be in its own 
> new thread)

   ok

> - immediately returns NGX_DONE (which then sends no response to the client)
> 

   ok

> [my output-generating code]
> - generates output (e.g. in its own thread)

   ok

> - returns ngx_http_output_filter(...) (if wanting to continue using 
> filters)
> - returns ngx_http_finalize_request(...) (if don't want to use any filters)
> 

   WARNING!

   As I have said, Nginx *is not* thread safe.
   You MUST not call ngx_http_output_filter, ngx_http_finalize_request,
   or any other Nginx function (with some exceptions) from your thread.

> [...]
>>> (5) Message is sent to Nginx that content has been generated through 
>>> some event
>>> (e.g. with a semaphore)
> If I've understood your comments above, then this notification actually 
> isn't necessary -
> you just call ngx_http_finalize_request (or ngx_http_output_filter?) 
> when you're done.
> 

No, don't do that if you use a separate thread.

> I was thinking that a response was automatically sent when you returned 
> from your handler.

No.
When you call ngx_http_output_filter, content may be sent to the client.
But control *must* return to Nginx as soon as possible (Nginx uses the 
so called cooperative multitasking).

>> If you can refactor you code, I suggest to execute the computation by 
>> steps.
> That's not really practical for what I'm doing - there's no guarantee 
> that the code can be executed quickly.

What do you need to do?

>> Of course if the codes involves some IO, this may be tricky.
>> But you can use the Nginx event module to receive IO notifications.
> Could you possibly give me an example?
> 

Again, see the code of mod_wsgi:
http://hg.mperillo.ath.cx/nginx/mod_wsgi/file/tip/src/ngx_wsgi.c

function State_register

As I have anticipated, this is rather complex.
You should also read Nginx source code to understand how things works.

> Thanks,
> 
> Marcus.
> 
> 


Manlio





More information about the nginx mailing list