How to wait for key in ngx.shared.DICT?

151 views
Skip to first unread message

rajalaks...@blis.com

unread,
Jun 8, 2022, 1:57:34 PM6/8/22
to openresty-en
Hello, 

Here is my use-case - 
  • Define a shared dictionary called 'requests'
  • In the init_by_lua_block, initialises a subscriber service that receives results and updates it in the shared dictionary
  • In the content_by_lua_block for the request handler, publishes the request to the app for processing and waits for results to arrive in the shared_dictionary via the subscriber service
Here is a prototype of what nginx.conf and my_app.lua look like -- 

nginx.conf 

worker_processes 8;
events {
    worker_connections 1024;
}
http { 
    lua_package_path "$prefix/lua/?.lua;;";
    lua_shared_dict requests 500m;
    init_by_lua_block { 
        require("my_app").subscribe()
    }
    server {
        listen 8080;
        location /app { 
            content_by_lua_block { 
                print require("my_app").process(ngx.var.arg_id) 
                ngx.eof()
            }
        }
    }
}

my_app.lua

local _M = {} 

-- Define publisher 
-- Define subscriber

function _M.subscribe()
while (true):
do
   message = subscriber:recv_string()
   id, value = string:match("([^,]+),([^,]+)")
   requests:safe_set(id, value)
end

function _M.publish()
   publisher:send(ngx.req.get_uri_args()["id"])
   -- How to wait here for key in shared dictionary with timeout? 
end

Any help around how to wait (non-blocking) for key to arrive in shared dictionary in the _M.publish() method above would be much appreciated. 

Thanks in advance,

Rajalakshmi



Igor Clark

unread,
Jun 8, 2022, 2:30:03 PM6/8/22
to openre...@googlegroups.com
Hello, I think you might want to have a look at ngx.timer.at or ngx.timer.every for this. They allow to spin up a function in a separate 'thread' (coroutines in lua) and have it repeat every N seconds (or fractions of seconds). Check out the docs. 

I'm not sure that polling in a shared dictionary is necessarily the way to go, especially if you've got some kind of while-true busy-loop in there, but I've  built a pub/sub pattern over a websocket where I run a client in an ngx.timer.at thread and push the incoming message content into a shared dictionary that gets accessed from elsewhere. That's when the messages are coming in from external sources, so that might not work here, but you could set up a local/internal websocket server (there's an openresty library for WS servers and clients) and manage the timing/coordination with multiple clients in multiple timer 'threads'. So even if polling is the way you want to go, then ngx.timer.* will likely help.

Hope that helps,
Igor

This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Blis Ltd, a company registered in England and Wales with registered number 06455773. Its registered office is 7th Floor, 10 Bloomsbury Way, WC1A 2SL, United Kingdom.

If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error.

--
You received this message because you are subscribed to the Google Groups "openresty-en" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openresty-en...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openresty-en/a493a997-e8f9-456b-9bc9-60fabee3b09dn%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages