On Sun, Mar 25, 2012 at 2:01 AM, <milspec@gmx.de> wrote:
> I do not know what is exactly meant with:
>
>> At least for kyotocabinet-lua-1.24, it is incorrectly using Lua globals
>> (rather than module-scoped variables) for its internal data structures,
>> which may cause troubles in the context of ngx_lua because ngx_lua's
>> global
>> scope is per-request and will be destroyed before each request completes.
>
In short, the kyotocabinet-lua library is badly written and requires
fixes. And its incorrect use of globals for its internal data causes
the error message that you're getting.
>
> Maybe agentzh can help you.
>
> The demo kcdbex1.lua of Kyoto Cabinet works only once in openresty per
> worker thread (see sourcecode below). As soon as it runs a second time, you
> get this error[1] which is not very descriptive. No website is sent then.
> But accessed the first time I get this answer on the web: "hop bar:step
> baz:jump foo:hop" which is the expected answer of this demo. I put
> kyotocabinet.so in the openresty/lualib directory.
>
> [1] "*1 lua handler aborted: runtime error: attempt to index a nil value"
>
See above.
> I think another problem is that with more than one worker-thread in nginx I
> end up with more than 1 database which is problematic as I only want one
> in-memory db used by all worker-threads altogether.
>
Sure, multi-worker mode here will be problematic as well. Have you
considered using redis for your applications? There's a nonblocking
client library for redis and ngx_lua:
https://github.com/agentzh/lua-resty-redis
Best regards,
-agentzh
>
> Kind regards,
>
>
> Thomas
>
>
> ##### modified_kcdbex1.lua (replace printf with ngx.say and db-path="+")
> ########
> kc = require("kyotocabinet")
>
> -- create the database object
> db = kc.DB:new()
>
> -- open the database
> if not db:open("+", kc.DB.OWRITER + kc.DB.OCREATE) then
> ngx.say("open error: " .. tostring(db:error()))
> end
>
> -- store records
> if not db:set("foo", "hop") or
> not db:set("bar", "step") or
> not db:set("baz", "jump") then
> ngx.say("set error: " .. tostring(db:error()))
> end
>
> -- retrieve records
> value = db:get("foo")
> if value then
> ngx.say(value)
> else
> ngx.say("get error: " .. tostring(db:error()))
> end
>
>
> -- traverse records
> cur = db:cursor()
> cur:jump()
> while true do
> local key, value = cur:get(true)
> if not key then break end
> ngx.say(key .. ":" .. value)
> end
> cur:disable()
>
>
> -- close the database
> if not db:close() then
> ngx.say("close error: " .. tostring(db:error()))
> end
>