<div dir="ltr">Hi,<div><br></div><div>   With the help of HttpLuaModule I'm trying to duplicate every request into two upstreams. Here is my configuration:</div><div><br></div><div>site.conf</div><div>---</div><div><br></div><div><div>upstream prod_upstream {</div><div>        server <a href="http://127.0.0.1:5000">127.0.0.1:5000</a>;</div><div>        server <a href="http://127.0.0.1:5001">127.0.0.1:5001</a>;</div><div>}</div><div><br></div><div>upstream dev_upstream {</div><div>        server <a href="http://127.0.0.1:6000">127.0.0.1:6000</a>;</div><div>}</div><div><br></div><div>server {</div><div>        location /prod {</div><div>                proxy_pass <a href="http://prod_upstream/">http://prod_upstream/</a>;</div><div>        }</div><div><br></div><div>        location /dev {</div><div>                proxy_pass <a href="http://dev_upstream/">http://dev_upstream/</a>;</div><div>        }</div><div><br></div><div>        location / {</div><div>                error_log "/tmp/error.log";</div><div>                content_by_lua_file /etc/nginx/luas/duplicator.lua;</div><div>        }</div><div>}</div><div><br></div><div>duplicator.lua</div><div>---</div><div><br></div><div><div>ngx.req.read_body()</div><div>local arguments = ngx.var.args</div><div><br></div><div>r1, r2 = ngx.location.capture_multi {</div><div>        { '/prod/', { args = arguments, share_all_vars = true } },</div><div>        { '/dev/', { args = arguments, share_all_vars = true } },</div><div>}</div><div><br></div><div>ngx.print(r1.body)</div></div><div><br></div><div><br></div><div>So far so good, all traffic destined to prod is being duplicated to dev and ONLY prod response is forwarded the client. </div><div><br></div><div>From the documentation here <a href="http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi">http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi</a> :</div><div><br></div><div>" ... This function will not return until all the subrequests terminate ... " </div><div><br></div><div>That is where my problem starts:</div><div><br></div><div>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. </div><div><br></div><div>I'm thinking about making /dev calls in an asynchronous way if possible. </div><div><br></div><div>My second approach:</div><div><br></div><div>duplicator_v2.lua:</div><div>---</div><div><br></div><div><div>gx.req.read_body()</div><div>local arguments = ngx.var.args</div><div><br></div><div>r1 = ngx.location.capture('/prod/', { args = arguments, share_all_vars = true })</div><div>ngx.print(r1.body)</div><div><br></div><div>r2 = ngx.location.capture('/dev/', { args = arguments, share_all_vars = true })</div></div><div><br></div><div><br></div><div>From the documentation of ngx.print: </div><div><br></div><div>" ... This is an asynchronous call and will return immediately without waiting for all the data to be written into the system send buffer ..."</div><div><br></div><div>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.</div><div><br></div><div>My final tests was this ugly configuration:</div><div><br></div><div><div>duplicator_v2.lua:</div><div>---</div><div><br></div><div><div>gx.req.read_body()</div><div>local arguments = ngx.var.args</div><div><br></div><div>r1 = ngx.location.capture('/prod/', { args = arguments, share_all_vars = true })</div><div>ngx.print(r1.body)</div><div>ngx.eof()</div><div><br></div><div>r2 = ngx.location.capture('/dev/', { args = arguments, share_all_vars = true })</div></div></div><div><br></div><div><br></div><div>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).</div><div><br></div><div><br></div><div>Is there a way to do capture calls in a asynchronous mode or to achieve this in other way?</div><div><br></div><div>Thank you in advance,</div><div><br></div><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">---<div>Guido Accardo</div></div></div>
</div></div>