I initiate Redis connection pool in redis.lua, by calling from C, I got a redis_lua_state
, this Lua state is global initiated once and other thread only get from it.
While there comes a HTTP request(worker thread), I need to fetch a redis connection from redis_lua_state
, then new another Lua state to load other Lua script, and these scripts will use this redis connection to communicate with Redis, how to do this? Or how to design my Lua scripts to make it simple?
Code Sample:
/* on main thread, to init redis pool connection */
lua_State *g_ls = NULL;
lua_State *init_redis_pool(void) {
int ret = 0;
g_ls = luaL_newstate();
lua_State *ls = g_ls;
luaL_openlibs(ls);
ret = luaL_loadfile(ls, "redis.lua");
const char *err;
(void)err;
/* preload */
ret = lua_pcall(ls, 0, 0, 0);
lua_getglobal(ls, "init_redis_pool");
ret = lua_pcall(ls, 0, 0, 0);
return ls;
}
/* worker thread */
int worker() {
...
lua_State *ls = luaL_newstate();
ret = luaL_loadfile(ls, "run.lua");
/* How to fetch data from g_ls? */
...
lua_getglobal(ls, "run")
ret = lua_pcall(ls, 0, 0, 0)
lua_close(ls);
...
return 0;
}
One way to do it is to implement copying variables between Lua states on C side. I have done a similar thing in my ERP project, but it requires a bit of a hassle, especially when it comes to copying user data.
What I did was to implement some sort of a super global variable (a C class in my instance) system that's implemented as
__index
and__newindex
of the global table, which is a proxy to default Lua global table. When setting a global variable,__newindex
would copy that to that super global. When another Lua state would try to access that global, it would retrieve it from the same structure.And then the redis connection could be a mutex locked shared, so when one state accesses it, the other cannot, for instance.
Of course there's the issue of accessing Lua default globals that you also have to take care of.
Alternatively, you can check out Lua lanes, if that's an option (I've no Redis experience, so don't know how open the Lua is, but I see that you have full access to C api, so it should work).
If your Lua states are separate, then there's no way to do this. Your worker thread will have to initialize the Redis connection and do processing on it.