This is an automated email from the ASF dual-hosted git repository. kichan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit e6147753cd65c3edd32b365e09b4d65edcffdd01 Author: Kit Chan <kic...@apache.org> AuthorDate: Sun Jul 8 21:43:42 2018 -0700 Add support for reloading the lua script in global plugin mode --- plugins/lua/ts_lua.c | 18 ++++++++++++++ plugins/lua/ts_lua_util.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ plugins/lua/ts_lua_util.h | 2 +- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/plugins/lua/ts_lua.c b/plugins/lua/ts_lua.c index cbfc782..ea73143 100644 --- a/plugins/lua/ts_lua.c +++ b/plugins/lua/ts_lua.c @@ -265,6 +265,15 @@ TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) } static int +configHandler(TSCont contp, TSEvent event ATS_UNUSED, void *edata ATS_UNUSED) +{ + TSDebug(TS_LUA_DEBUG_TAG, "[%s] calling configuration handler", __FUNCTION__); + ts_lua_instance_conf *conf = (ts_lua_instance_conf *)TSContDataGet(contp); + ts_lua_reload_module(conf, ts_lua_g_main_ctx_array, conf->states); + return 0; +} + +static int globalHookHandler(TSCont contp, TSEvent event ATS_UNUSED, void *edata) { TSHttpTxn txnp = (TSHttpTxn)edata; @@ -597,4 +606,13 @@ TSPluginInit(int argc, const char *argv[]) lua_pop(l, 1); ts_lua_destroy_http_ctx(http_ctx); + + TSCont config_contp = TSContCreate(configHandler, NULL); + if (!config_contp) { + TSError("[ts_lua][%s] could not create configuration continuation", __FUNCTION__); + return; + } + TSContDataSet(config_contp, conf); + + TSMgmtUpdateRegister(config_contp, "ts_lua"); } diff --git a/plugins/lua/ts_lua_util.c b/plugins/lua/ts_lua_util.c index 9455c1b..b72b076 100644 --- a/plugins/lua/ts_lua_util.c +++ b/plugins/lua/ts_lua_util.c @@ -315,6 +315,69 @@ ts_lua_del_module(ts_lua_instance_conf *conf, ts_lua_main_ctx *arr, int n) } int +ts_lua_reload_module(ts_lua_instance_conf *conf, ts_lua_main_ctx *arr, int n) +{ + int i; + lua_State *L; + + for (i = 0; i < n; i++) { + TSMutexLock(arr[i].mutexp); + + L = arr[i].lua; + + /* call "__reload__", to clean resources if necessary */ + lua_pushlightuserdata(L, conf); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_replace(L, LUA_GLOBALSINDEX); /* L[GLOBAL] = L[REG][conf] */ + + lua_getglobal(L, "__reload__"); /* get __clean__ function */ + + if (lua_type(L, -1) == LUA_TFUNCTION) { + if (lua_pcall(L, 0, 0, 0)) { + TSError("[ts_lua][%s] lua_pcall %s failed: %s", __FUNCTION__, conf->script, lua_tostring(L, -1)); + } + } else { + lua_pop(L, 1); /* pop nil */ + } + + // new global context + lua_newtable(L); /* new TB1 */ + lua_pushvalue(L, -1); /* new TB2 */ + lua_setfield(L, -2, "_G"); /* TB1[_G] = TB2 empty table, we can change _G to xx */ + lua_newtable(L); /* new TB3 */ + lua_rawgeti(L, LUA_REGISTRYINDEX, arr[i].gref); /* push L[GLOBAL] */ + lua_setfield(L, -2, "__index"); /* TB3[__index] = L[GLOBAL] which has ts.xxx api */ + lua_setmetatable(L, -2); /* TB1[META] = TB3 */ + lua_replace(L, LUA_GLOBALSINDEX); /* L[GLOBAL] = TB1 */ + + ts_lua_set_instance_conf(L, conf); + + if (strlen(conf->script)) { + if (luaL_loadfile(L, conf->script)) { + TSError("[ts_lua][%s] luaL_loadfile %s failed: %s", __FUNCTION__, conf->script, lua_tostring(L, -1)); + } else { + if (lua_pcall(L, 0, 0, 0)) { + TSError("[ts_lua][%s] lua_pcall %s failed: %s", __FUNCTION__, conf->script, lua_tostring(L, -1)); + } + } + } + + lua_pushlightuserdata(L, conf); + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_rawset(L, LUA_REGISTRYINDEX); /* L[REG][conf] = L[GLOBAL] */ + + lua_newtable(L); + lua_replace(L, LUA_GLOBALSINDEX); /* L[GLOBAL] = EMPTY */ + + lua_gc(L, LUA_GCCOLLECT, 0); + + TSMutexUnlock(arr[i].mutexp); + } + + return 0; +} + +int ts_lua_init_instance(ts_lua_instance_conf *conf ATS_UNUSED) { return 0; diff --git a/plugins/lua/ts_lua_util.h b/plugins/lua/ts_lua_util.h index e0025ef..d75db9f 100644 --- a/plugins/lua/ts_lua_util.h +++ b/plugins/lua/ts_lua_util.h @@ -28,8 +28,8 @@ void ts_lua_script_register(lua_State *L, char *script, ts_lua_instance_conf *co int ts_lua_add_module(ts_lua_instance_conf *conf, ts_lua_main_ctx *arr, int n, int argc, char *argv[], char *errbuf, int errbuf_len); - int ts_lua_del_module(ts_lua_instance_conf *conf, ts_lua_main_ctx *arr, int n); +int ts_lua_reload_module(ts_lua_instance_conf *conf, ts_lua_main_ctx *arr, int n); int ts_lua_init_instance(ts_lua_instance_conf *conf); int ts_lua_del_instance(ts_lua_instance_conf *conf);