Welcome! Log In Create A New Profile

Advanced

HttpLuaModule create asynchronous subrequests

Guido Accardo
November 12, 2014 03:22PM
Hi,

With the help of HttpLuaModule I'm trying to duplicate every request
into two upstreams. Here is my configuration:

site.conf
---

upstream prod_upstream {
server 127.0.0.1:5000;
server 127.0.0.1:5001;
}

upstream dev_upstream {
server 127.0.0.1:6000;
}

server {
location /prod {
proxy_pass http://prod_upstream/;
}

location /dev {
proxy_pass http://dev_upstream/;
}

location / {
error_log "/tmp/error.log";
content_by_lua_file /etc/nginx/luas/duplicator.lua;
}
}

duplicator.lua
---

ngx.req.read_body()
local arguments = ngx.var.args

r1, r2 = ngx.location.capture_multi {
{ '/prod/', { args = arguments, share_all_vars = true } },
{ '/dev/', { args = arguments, share_all_vars = true } },
}

ngx.print(r1.body)


So far so good, all traffic destined to prod is being duplicated to dev and
ONLY prod response is forwarded the client.

From the documentation here
http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi :

" ... This function will not return until all the subrequests terminate ...
"

That is where my problem starts:

I'm working with a real time distributed system so the response time can't
be longer than 50ms. Dev is definitely slower so I can't wait for dev
response. Also Imagine if /dev is broken the timeout will take too much
time.

I'm thinking about making /dev calls in an asynchronous way if possible.

My second approach:

duplicator_v2.lua:
---

gx.req.read_body()
local arguments = ngx.var.args

r1 = ngx.location.capture('/prod/', { args = arguments, share_all_vars =
true })
ngx.print(r1.body)

r2 = ngx.location.capture('/dev/', { args = arguments, share_all_vars =
true })


From the documentation of ngx.print:

" ... This is an asynchronous call and will return immediately without
waiting for all the data to be written into the system send buffer ..."

I was hopping that splitting the captures and using ngx.print before the
second call will do what I need, answer to the client and continue with
calling /dev but that doesn't happen, works exactly as the first approach.

My final tests was this ugly configuration:

duplicator_v2.lua:
---

gx.req.read_body()
local arguments = ngx.var.args

r1 = ngx.location.capture('/prod/', { args = arguments, share_all_vars =
true })
ngx.print(r1.body)
ngx.eof()

r2 = ngx.location.capture('/dev/', { args = arguments, share_all_vars =
true })


Here, prod response is sent immediately as I want and dev receives the
traffic but the connection is closed the I got a Broken Pipe (which makes
sense).


Is there a way to do capture calls in a asynchronous mode or to achieve
this in other way?

Thank you in advance,


--
---
Guido Accardo
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Subject Author Posted

HttpLuaModule create asynchronous subrequests

Guido Accardo November 12, 2014 03:22PM

Re: HttpLuaModule create asynchronous subrequests

Yichun Zhang (agentzh) November 13, 2014 03:26PM

Re: HttpLuaModule create asynchronous subrequests

Guido Accardo November 14, 2014 02:22PM

Re: HttpLuaModule create asynchronous subrequests

Yichun Zhang (agentzh) November 14, 2014 04:42PM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 192
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready