Hey!
I need to take an incoming request and send it up to multiple upstreams at once. I've sorted out a way to do this using ngx.location.capture_multi and nginx variables, but I don't really like that I'm using a dummy location to declare the $pool variable. The code below effectively captures what I'm trying to do (I've omitted parts that aren't relevant to this discussion, and IRL I'm building the subrequests and unpacking the responses dynamically to accommodate several pools).
server {
upstream pool_0 {
server "127.0.0.1:26157;
}
upstream pool_1 {
server "127.0.0.1:26158;
}
rewrite_by_lua '
if ngx.req.get_headers()["X-Flag"] then
-- this is a subrequest
if ngx.var.pool == 0 then
target_upstream = pool_0
elseif ngx.var.pool == 1 then
target_upstream = pool_1
end
else
-- this is the original request
ngx.req.set_header("X-Flag", 1)
ngx.req.read_body()
resps = { ngx.location.capture_multi( {{ngx.var.request_uri, vars = {pool=x}}, {ngx.var.request_uri, {pool=y}} }) }
-- unpack responses, find the successful one and send it back to client
end
';
location / {
set $target_upstream foo;
proxy_pass http://$target_upstream
}
location /dummy_for_variable_declaration {
internal;
set $pool -1;
}
Note that the above code works because nginx declares variables when it encounters a "set" while loading the config file. However, the subrequest doesn't enter the /dummy_for_variable_declaration location, so its "set" directive doesn't get executed. If I declare $pool anywhere else, then the value I assign to $pool for the subrequest gets overwritten in the subrequest rewrite phase.
Is there another/better way to do this? Again, I don't like that I'm using this dummy location.
Thanks!
-Gavin