Hello!
On Fri, Aug 15, 2014 at 4:01 PM, Lionel Duboeuf wrote:
> Maybe i did not explain well my problem.
> In fact, i've a table in a lua file that is loaded within init_by_lua phase.
> This table (file) will have to be updated with new directives arriving from
> HTTP request so that at next stop|start of the nginx master process, there
> is no data loss.
One implementation approach is like this:
1. In init_by_lua, load a data file (for example, in the JSON format),
say, /tmp/route.json, from your Lua code, and insert the raw data
(like JSON) into a lua_shared_dict zone, say, ngx.shared.route.
2. In your request handler, say, content_by_lua, try to check if your
worker-level Lua table is up to date with your ngx.shared.route
content (you can introduce a version number or checksum here). If it
is not up to date, load the ngx.shared.route content into your
worker-level Lua table. Then query your worker-level Lua table
directly.
3. In your init_worker_by_lua handler, use ngx.timer.at() to initiate
a re-occurring timer that periodically tries to flush the
ngx.shared.route content directly to your original file, say,
/tmp/route.json. You can use a tmp file as an intermediate, only when
you have successfully flushed the data into the tmp file, you move the
tmp file as your target file, say, /tmp/route.json. You should not use
too small timer delay here. Seconds should be fine. To prevent
multiple workers from flushing the data to the file at the same time,
you can use the lua-resty-lock library to ensure that only one worker
is doing this.
4. You expose a special HTTP service in a dedicated location that can
update your ngx.shared.route shm zone from outside.
Another approach is to use an external data service (like Redis) that
supports persistence out of the box and just cache the query result
(via lua-resty-redis, for example) in your nginx through something
like the lua-resty-lrucache library.
Both approaches have their own cons and pros. It's up to you to make a decision.
> Regarding Thread-Safety, the question was : if a worker "A" and worker "B"
> try to persist the shared table at the same time, will that fail ?
>
If you mean flushing data into a file, then you need to prevent
multiple worker processes from doing this at the same time by
something like the lua-resty-lock library (see above).
Regards,
-agentzh