Non blocking delay in header filters

Dipl. Ing. Sergey Brester serg.brester at sebres.de
Fri Apr 21 09:05:18 UTC 2023


 

Well, it is impossible if you'd use some memory blocks allocated by
nginx within main request.
The memory allocated inside the request is released on request end. 

An example how one can implement non-blocking delay can you see in
https://github.com/openresty/echo-nginx-module#echo_sleep [2]. 

But again, ensure you have not stored references to some main request
structures (request related memory range). If you'd need some of them
(e. g. headers, args, etc), duplicate them and release in event handler
if timer becomes set or after processing your sub-requests. 

However if I were you, I'd rather implement it on a backend side (not in
nginx), e. g. using background sub-requests either with post_action
(despite nonofficial undocumented) or with mirror [3], configured in a
corresponding location.
Especially if one expects some transaction safety (e. g. for save
operation in corner cases like nginx restart/reload/shutdown/etc during
the delay between main response and all the sub-requests) as a pipeline
similar procedure.
So one could register each step (your delayed request) in some queue,
for instance storing the request chain in a database or file, to get it
safe against shutdown.
Although also without the transaction safety your approach to implement
it completely in nginx is questionable for many reasons (particularly if
the delay is not something artificial, but rather a real timing event). 

Regards,
Serg. 

20.04.2023 18:46, Ava Hahn wrote via nginx-devel: 

> Hello All, 
> 
> I am currently implementing a response header filter that triggers one or more subrequests conditionally based on the status of the parent response.
> 
> I want to introduce some delay between the checking of the response and the triggering of the subrequest, but I do not want to block the worker thread.
> 
> So far I have allocated an event within the main request's pool, added a timer with my desired delay, and attached a callback that does two things. 
> 
> * triggers a subrequest as desired
> * proceeds to call the next response header filter
> 
> In the meantime, after posting the event my handler returns NGX_OK.
> 
> This is not working at all. Shortly after my filter returns NGX_OK the response is finalized, and the pool is deallocated. When the timer wakes up a segfault occurs in the worker process (in ngx_event_del_timer). Even if I allocate the event in a separate pool that outlives the request it is still not defined what happens when I try to trigger a subrequest on a request that has been finalized.
> 
> My question is how can I make the finalization of the request contingent on the associated/posted event being handled first?
> 
> OR, is there another facility for implementing non blocking delay that I can use?
> 
> Thanks,
> Ava 
> 
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> https://mailman.nginx.org/mailman/listinfo/nginx-devel [1]
 

Links:
------
[1] https://mailman.nginx.org/mailman/listinfo/nginx-devel
[2] https://github.com/openresty/echo-nginx-module#echo_sleep
[3] http://nginx.org/en/docs/http/ngx_http_mirror_module.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20230421/b213dbd1/attachment.htm>


More information about the nginx-devel mailing list