On Tuesday, May 7, 2013 1:20:31 AM UTC+2, agentzh wrote:
Hello!
I can see your point here but your example does not make much sense
for the current ngx_lua and nginx architecture because
1. Nginx can have multiple worker processes and resources like "light
threads" are always limited to the current worker process creating
them and they cannot be shared among all the worker processes.
Is it possible to have per worker sticky session? The pub-sub example was just a toy... In practice,
2. The "light threads" created in a request handler (like
content_by_lua) have a lifetime no longer than the current request
handler. So we cannot yield a "light thread" in a request and resume
it later in another thread according to the current design.
As I imagined it, ngx.thread.yield() would also suspend the request handler, and .resume would resume it... Is it possible?
> Using a similar technique, one could implement cosocket-based message queue
> clients. By using a timer, you could spawn an independent thread which would
> itself spawn two children. One that listens to the socket, and the other
> that would be resumed to send data...
>
There's no listening cosockets yet in ngx_lua :)
Here's what I have in mind... to be required and used in init_by_lua (I know that cosocckets are not available at that point at the moment... Let's imagine):
local ngx = require"ngx"
module"permanent_connection"
connect = function(connection_params)
local handlers, ret = {}, {} -- ret
ngx.timer.at(0, function()
local socket = ngx.socket.tcp()
socket:connect(connection_params)
local sender = ngx.thread.create(function(req,callback)
while true do
if req then (callback or noop)(socket:send(req))
req, callback = ngx.thread.yield()
end
end)
function ret.send(...)
ngx.thread.resume(sender,...)
end
local receiver = ngx.thread.spawn(function()
while true do
local raw = socket:receive("*l")
local success, data = ""> if success then for _, h in handlers do
h(data) -- or resume threads?
end
end
end
ngx.thread.resume(receiver)
end)
function ret.register_handler(h)
handlers:insert(h)
end
return ret
end
You should put init_by_lua directly into the http {} block. As in
http {
init_by_lua '...';
server {
...
}
}
Ok, thanks, I had tried to put it here, but without the trailing semi-column, and didn't notice that the error message was different. Noob mistake :-)
Regards,
-- Pierre-Yves