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 2016/01/21 08:26:56 UTC
trafficserver git commit: TS-4129: Support TSContSchedule in ts_lua
plugin. This closes #420
Repository: trafficserver
Updated Branches:
refs/heads/master b6680179a -> d30401990
TS-4129: Support TSContSchedule in ts_lua plugin. This closes #420
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/d3040199
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/d3040199
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/d3040199
Branch: refs/heads/master
Commit: d30401990ada424cb0b6acbcb4cfeab31bdb979f
Parents: b668017
Author: Kit Chan <ki...@apache.org>
Authored: Wed Jan 20 23:26:42 2016 -0800
Committer: Kit Chan <ki...@apache.org>
Committed: Wed Jan 20 23:26:42 2016 -0800
----------------------------------------------------------------------
doc/admin-guide/plugins/ts_lua.en.rst | 30 +++++
.../ts_lua/example/test_schedule.lua | 48 +++++++
plugins/experimental/ts_lua/ts_lua_misc.c | 124 +++++++++++++++++++
plugins/experimental/ts_lua/ts_lua_util.c | 41 ++++++
plugins/experimental/ts_lua/ts_lua_util.h | 3 +
5 files changed, 246 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d3040199/doc/admin-guide/plugins/ts_lua.en.rst
----------------------------------------------------------------------
diff --git a/doc/admin-guide/plugins/ts_lua.en.rst b/doc/admin-guide/plugins/ts_lua.en.rst
index 66de2d9..2cc8dc2 100644
--- a/doc/admin-guide/plugins/ts_lua.en.rst
+++ b/doc/admin-guide/plugins/ts_lua.en.rst
@@ -2379,6 +2379,36 @@ Here is an example:
`TOP <#ts-lua-plugin>`_
+ts.schedule
+-----------
+**syntax:** *ts.schedule(THREAD_TYPE, sec, FUNCTION, param1?, param2?, ...)*
+
+**context:** *after do_remap*
+
+**description:** Schedule function to be run after specified seconds without blocking.
+
+Behind the scene, this method makes use of the ATS event model.
+
+Here is an example:
+
+::
+
+ function schedule()
+ ts.debug('test schedule starts')
+ end
+
+ function cache_lookup()
+ ts.debug('cache-lookup')
+ ts.schedule(TS_LUA_THREAD_POOL_NET, 0, schedule)
+ return 0
+ end
+
+ function do_remap()
+ ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+ end
+
+`TOP <#ts-lua-plugin>`_
+
ts.http.config_int_get
----------------------
**syntax:** *val = ts.http.config_int_get(CONFIG)*
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d3040199/plugins/experimental/ts_lua/example/test_schedule.lua
----------------------------------------------------------------------
diff --git a/plugins/experimental/ts_lua/example/test_schedule.lua b/plugins/experimental/ts_lua/example/test_schedule.lua
new file mode 100644
index 0000000..d80e843
--- /dev/null
+++ b/plugins/experimental/ts_lua/example/test_schedule.lua
@@ -0,0 +1,48 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+
+function schedule()
+ ts.debug('test schedule starts')
+
+ -- test.com needs to be handled by ATS in remap.config
+ local url = 'http://test.com/test.php'
+ local res = ts.fetch(url)
+ ts.debug('test fetch')
+ if res.status == 200 then
+ local b = res.body
+ local len = string.len(b)
+ ts.debug(len)
+ end
+ ts.debug('test schedule ends')
+end
+
+function cache_lookup()
+ ts.debug('cache-lookup')
+ ts.schedule(TS_LUA_THREAD_POOL_NET, 0, schedule)
+ return 0
+end
+
+function do_global_read_request()
+ local inner = ts.http.is_internal_request()
+ if inner ~= 0 then
+ ts.debug('internal')
+ return 0
+ end
+
+ ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+ return 0
+end
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d3040199/plugins/experimental/ts_lua/ts_lua_misc.c
----------------------------------------------------------------------
diff --git a/plugins/experimental/ts_lua/ts_lua_misc.c b/plugins/experimental/ts_lua/ts_lua_misc.c
index 5fc5b00..e9f8223 100644
--- a/plugins/experimental/ts_lua/ts_lua_misc.c
+++ b/plugins/experimental/ts_lua/ts_lua_misc.c
@@ -24,9 +24,13 @@ static int ts_lua_get_now_time(lua_State *L);
static int ts_lua_debug(lua_State *L);
static int ts_lua_error(lua_State *L);
static int ts_lua_sleep(lua_State *L);
+static int ts_lua_schedule(lua_State *L);
static int ts_lua_sleep_cleanup(ts_lua_async_item *ai);
static int ts_lua_sleep_handler(TSCont contp, TSEvent event, void *edata);
+static int ts_lua_schedule_handler(TSCont contp, TSEvent event, void *edata);
+
+static void ts_lua_inject_misc_variables(lua_State *L);
void
ts_lua_inject_misc_api(lua_State *L)
@@ -46,6 +50,21 @@ ts_lua_inject_misc_api(lua_State *L)
/* ts.sleep(...) */
lua_pushcfunction(L, ts_lua_sleep);
lua_setfield(L, -2, "sleep");
+
+ /* ts.schedule(...) */
+ lua_pushcfunction(L, ts_lua_schedule);
+ lua_setfield(L, -2, "schedule");
+
+ ts_lua_inject_misc_variables(L);
+}
+
+static void
+ts_lua_inject_misc_variables(lua_State *L)
+{
+ lua_pushinteger(L, TS_THREAD_POOL_NET);
+ lua_setglobal(L, "TS_LUA_THREAD_POOL_NET");
+ lua_pushinteger(L, TS_THREAD_POOL_TASK);
+ lua_setglobal(L, "TS_LUA_THREAD_POOL_TASK");
}
static int
@@ -82,6 +101,111 @@ ts_lua_error(lua_State *L)
}
static int
+ts_lua_schedule(lua_State *L)
+{
+ int sec;
+ int type;
+ int entry;
+
+ ts_lua_http_ctx *actx;
+
+ int n;
+
+ TSCont contp;
+ ts_lua_cont_info *ci;
+ ts_lua_cont_info *nci;
+
+ ci = ts_lua_get_cont_info(L);
+ if (ci == NULL)
+ return 0;
+
+ entry = lua_tointeger(L, 1);
+
+ sec = luaL_checknumber(L, 2);
+ if (sec < 1) {
+ sec = 0;
+ }
+
+ type = lua_type(L, 3);
+ if (type != LUA_TFUNCTION)
+ return 0;
+
+ n = lua_gettop(L);
+
+ if (n < 3) {
+ TSError("[ts_lua] ts.http.schedule need at least three params");
+ return 0;
+ }
+
+ // TO-DO unset the original context in L
+ actx = ts_lua_create_async_ctx(L, ci, n);
+
+ contp = TSContCreate(ts_lua_schedule_handler, ci->mutex);
+ TSContDataSet(contp, actx);
+
+ nci = &actx->cinfo;
+ nci->contp = contp;
+ nci->mutex = ci->mutex;
+
+ TSContSchedule(contp, sec * 1000, entry);
+
+ return 0;
+}
+
+static int
+ts_lua_schedule_handler(TSCont contp, TSEvent ev, void *edata)
+{
+ lua_State *L;
+ ts_lua_cont_info *ci;
+ ts_lua_coroutine *crt;
+ int event, n, ret, rc;
+ ts_lua_http_ctx *actx;
+ ts_lua_main_ctx *main_ctx;
+
+ event = (int)ev;
+ TSDebug(TS_LUA_DEBUG_TAG, "getting actx and other info");
+ actx = (ts_lua_http_ctx *)TSContDataGet(contp);
+
+ TSDebug(TS_LUA_DEBUG_TAG, "getting http_Ctx");
+ ci = &actx->cinfo;
+ crt = &ci->routine;
+
+ main_ctx = crt->mctx;
+ L = crt->lua;
+
+ rc = ret = 0;
+
+ TSMutexLock(main_ctx->mutexp);
+ ts_lua_set_cont_info(L, ci);
+
+ if (event == TS_LUA_EVENT_COROUTINE_CONT) {
+ TSDebug(TS_LUA_DEBUG_TAG, "event is coroutine_cont");
+ n = (intptr_t)edata;
+ ret = lua_resume(L, n);
+ } else {
+ TSDebug(TS_LUA_DEBUG_TAG, "event is not coroutine_cont");
+ n = lua_gettop(L);
+ ret = lua_resume(L, n - 1);
+ }
+
+ if (ret == LUA_YIELD) {
+ TSMutexUnlock(main_ctx->mutexp);
+ goto done;
+ }
+
+ if (ret != 0) {
+ TSError("[ts_lua] lua_resume failed: %s", lua_tostring(L, -1));
+ }
+
+ lua_pop(L, lua_gettop(L));
+ TSMutexUnlock(main_ctx->mutexp);
+ ts_lua_destroy_async_ctx(actx);
+
+done:
+ return 0;
+}
+
+static int
ts_lua_sleep(lua_State *L)
{
int sec;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d3040199/plugins/experimental/ts_lua/ts_lua_util.c
----------------------------------------------------------------------
diff --git a/plugins/experimental/ts_lua/ts_lua_util.c b/plugins/experimental/ts_lua/ts_lua_util.c
index ddef163..19e0bac 100644
--- a/plugins/experimental/ts_lua/ts_lua_util.c
+++ b/plugins/experimental/ts_lua/ts_lua_util.c
@@ -338,6 +338,47 @@ ts_lua_get_cont_info(lua_State *L)
return ci;
}
+ts_lua_http_ctx *
+ts_lua_create_async_ctx(lua_State *L, ts_lua_cont_info *hci, int n)
+{
+ int i;
+ lua_State *l;
+ ts_lua_coroutine *crt;
+ ts_lua_http_ctx *actx;
+
+ actx = TSmalloc(sizeof(ts_lua_http_ctx));
+ memset(actx, 0, sizeof(ts_lua_http_ctx));
+
+ // create lua_thread
+ l = lua_newthread(L);
+
+ // init the coroutine
+ crt = &actx->cinfo.routine;
+ crt->mctx = hci->routine.mctx;
+ crt->lua = l;
+ crt->ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ // replace the param; start with 2 because first two params are not needed
+ for (i = 2; i < n; i++) {
+ lua_pushvalue(L, i + 1);
+ }
+
+ lua_xmove(L, l, n - 2);
+
+ return actx;
+}
+
+void
+ts_lua_destroy_async_ctx(ts_lua_http_ctx *http_ctx)
+{
+ ts_lua_cont_info *ci;
+
+ ci = &http_ctx->cinfo;
+
+ ts_lua_release_cont_info(ci);
+ TSfree(http_ctx);
+}
+
void
ts_lua_set_http_ctx(lua_State *L, ts_lua_http_ctx *ctx)
{
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d3040199/plugins/experimental/ts_lua/ts_lua_util.h
----------------------------------------------------------------------
diff --git a/plugins/experimental/ts_lua/ts_lua_util.h b/plugins/experimental/ts_lua/ts_lua_util.h
index 7cd7675..e3dc9a9 100644
--- a/plugins/experimental/ts_lua/ts_lua_util.h
+++ b/plugins/experimental/ts_lua/ts_lua_util.h
@@ -39,6 +39,9 @@ ts_lua_instance_conf *ts_lua_get_instance_conf(lua_State *L);
void ts_lua_set_cont_info(lua_State *L, ts_lua_cont_info *ci);
ts_lua_cont_info *ts_lua_get_cont_info(lua_State *L);
+ts_lua_http_ctx *ts_lua_create_async_ctx(lua_State *L, ts_lua_cont_info *hci, int n);
+void ts_lua_destroy_async_ctx(ts_lua_http_ctx *http_ctx);
+
void ts_lua_set_http_ctx(lua_State *L, ts_lua_http_ctx *ctx);
ts_lua_http_ctx *ts_lua_get_http_ctx(lua_State *L);