You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ki...@apache.org on 2018/07/11 20:42:12 UTC

[trafficserver] 01/02: Add support for reloading the lua script in global plugin mode

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 <ki...@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);