Skip to content

Commit

Permalink
feature: added new Lua API, ngx.timer.at(time, callback), for definin…
Browse files Browse the repository at this point in the history
…g timers that can run the user callback as a Lua "light thread" (detached from the current request) after the time (in seconds) specified. also added new configure directives lua_max_pending_timers and lua_max_running_timers for limiting the number of pending timers and "running" timers.
  • Loading branch information
agentzh committed Apr 2, 2013
1 parent 664d74e commit 2ac8d89
Show file tree
Hide file tree
Showing 32 changed files with 5,742 additions and 53 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,10 @@ tre
src/phase.[ch]
src/probe.h
src/uthread.[ch]
src/timer.[ch]
*.plist
lua
ttimer
Makefile
tsubreq
tthread
Expand Down
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/src/ngx_http_lua_req_method.c \
$ngx_addon_dir/src/ngx_http_lua_phase.c \
$ngx_addon_dir/src/ngx_http_lua_uthread.c \
$ngx_addon_dir/src/ngx_http_lua_timer.c \
"

NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
Expand Down Expand Up @@ -270,6 +271,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
$ngx_addon_dir/src/ngx_http_lua_phase.h \
$ngx_addon_dir/src/ngx_http_lua_probe.h \
$ngx_addon_dir/src/ngx_http_lua_uthread.h \
$ngx_addon_dir/src/ngx_http_lua_timer.h \
"

CFLAGS="$CFLAGS -DNDK_SET_VAR"
Expand Down
2 changes: 1 addition & 1 deletion src/ngx_http_lua_accessby.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
}

if (rc == NGX_DONE) {
ngx_http_finalize_request(r, NGX_DONE);
ngx_http_lua_finalize_request(r, NGX_DONE);

rc = ngx_http_lua_run_posted_threads(c, L, r, ctx);

Expand Down
8 changes: 7 additions & 1 deletion src/ngx_http_lua_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ ngx_http_lua_ngx_req_set_uri_args(lua_State *L) {
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

switch (lua_type(L, 1)) {
case LUA_TNUMBER:
case LUA_TSTRING:
Expand Down Expand Up @@ -113,6 +115,8 @@ ngx_http_lua_ngx_req_get_uri_args(lua_State *L) {
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

lua_createtable(L, 0, 4);

/* we copy r->args over to buf to simplify
Expand Down Expand Up @@ -171,8 +175,10 @@ ngx_http_lua_ngx_req_get_post_args(lua_State *L)
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

if (r->discard_body) {
lua_createtable(L, 0, 4);
lua_createtable(L, 0, 0);
return 1;
}

Expand Down
15 changes: 11 additions & 4 deletions src/ngx_http_lua_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ typedef struct {
#define NGX_HTTP_LUA_CONTEXT_LOG 0x10
#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x20
#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x40
#define NGX_HTTP_LUA_CONTEXT_TIMER 0x80


typedef struct ngx_http_lua_main_conf_s ngx_http_lua_main_conf_t;
Expand All @@ -100,6 +101,12 @@ struct ngx_http_lua_main_conf_s {

ngx_pool_t *pool;

ngx_int_t max_pending_timers;
ngx_int_t pending_timers;

ngx_int_t max_running_timers;
ngx_int_t running_timers;

#if (NGX_PCRE)
ngx_int_t regex_cache_entries;
ngx_int_t regex_cache_max_entries;
Expand Down Expand Up @@ -271,10 +278,6 @@ struct ngx_http_lua_co_ctx_s {


typedef struct ngx_http_lua_ctx_s {
uint8_t context; /* the current running directive context
(or running phase) for the current
Lua chunk */

ngx_http_handler_pt resume_handler;

ngx_http_lua_co_ctx_t *cur_co_ctx; /* co ctx for the current coroutine */
Expand Down Expand Up @@ -326,6 +329,10 @@ typedef struct ngx_http_lua_ctx_s {

ngx_http_lua_posted_thread_t *posted_threads;

uint16_t context; /* the current running directive context
(or running phase) for the current
Lua chunk */

unsigned run_post_subrequest:1; /* whether it has run
post_subrequest
(for subrequests only) */
Expand Down
14 changes: 8 additions & 6 deletions src/ngx_http_lua_contentby.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@


static void ngx_http_lua_content_phase_post_read(ngx_http_request_t *r);
static ngx_int_t ngx_http_lua_content_run_posted_threads(lua_State *L,
ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, int n);


ngx_int_t
Expand Down Expand Up @@ -220,7 +218,7 @@ ngx_http_lua_content_phase_post_read(ngx_http_request_t *r)

if (ctx->waiting_more_body) {
ctx->waiting_more_body = 0;
ngx_http_finalize_request(r, ngx_http_lua_content_handler(r));
ngx_http_lua_finalize_request(r, ngx_http_lua_content_handler(r));

} else {
r->main->count--;
Expand Down Expand Up @@ -313,13 +311,15 @@ ngx_http_lua_content_handler_inline(ngx_http_request_t *r)
}


static ngx_int_t
ngx_int_t
ngx_http_lua_content_run_posted_threads(lua_State *L, ngx_http_request_t *r,
ngx_http_lua_ctx_t *ctx, int n)
{
ngx_int_t rc;
ngx_http_lua_posted_thread_t *pt;

dd("run posted threads: %p", ctx->posted_threads);

for ( ;; ) {
pt = ctx->posted_threads;
if (pt == NULL) {
Expand All @@ -331,6 +331,8 @@ ngx_http_lua_content_run_posted_threads(lua_State *L, ngx_http_request_t *r,
ngx_http_lua_probe_run_posted_thread(r, pt->co_ctx->co,
(int) pt->co_ctx->co_status);

dd("posted thread status: %d", pt->co_ctx->co_status);

if (pt->co_ctx->co_status != NGX_HTTP_LUA_CO_RUNNING) {
continue;
}
Expand All @@ -350,7 +352,7 @@ ngx_http_lua_content_run_posted_threads(lua_State *L, ngx_http_request_t *r,

if (rc == NGX_OK) {
while (n > 0) {
ngx_http_finalize_request(r, NGX_DONE);
ngx_http_lua_finalize_request(r, NGX_DONE);
n--;
}

Expand All @@ -375,7 +377,7 @@ ngx_http_lua_content_run_posted_threads(lua_State *L, ngx_http_request_t *r,
/* n > 1 */

do {
ngx_http_finalize_request(r, NGX_DONE);
ngx_http_lua_finalize_request(r, NGX_DONE);
} while (--n > 1);

return NGX_DONE;
Expand Down
2 changes: 2 additions & 0 deletions src/ngx_http_lua_contentby.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ void ngx_http_lua_content_wev_handler(ngx_http_request_t *r);
ngx_int_t ngx_http_lua_content_handler_file(ngx_http_request_t *r);
ngx_int_t ngx_http_lua_content_handler_inline(ngx_http_request_t *r);
ngx_int_t ngx_http_lua_content_handler(ngx_http_request_t *r);
ngx_int_t ngx_http_lua_content_run_posted_threads(lua_State *L,
ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, int n);


#endif /* _NGX_HTTP_LUA_CONTENT_BY_H_INCLUDED_ */
Expand Down
5 changes: 4 additions & 1 deletion src/ngx_http_lua_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ ngx_http_lua_ngx_exit(lua_State *L)

ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
| NGX_HTTP_LUA_CONTEXT_ACCESS
| NGX_HTTP_LUA_CONTEXT_CONTENT);
| NGX_HTTP_LUA_CONTEXT_CONTENT
| NGX_HTTP_LUA_CONTEXT_TIMER);

rc = (ngx_int_t) luaL_checkinteger(L, 1);

Expand Down Expand Up @@ -378,6 +379,8 @@ ngx_http_lua_on_abort(lua_State *L)
return luaL_error(L, "no request ctx found");
}

ngx_http_lua_check_fake_request2(L, r, ctx);

if (ctx->on_abort_co_ctx) {
lua_pushnil(L);
lua_pushliteral(L, "duplicate call");
Expand Down
12 changes: 8 additions & 4 deletions src/ngx_http_lua_coroutine.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ ngx_http_lua_coroutine_create_helper(lua_State *L, ngx_http_request_t *r,

ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
| NGX_HTTP_LUA_CONTEXT_ACCESS
| NGX_HTTP_LUA_CONTEXT_CONTENT);
| NGX_HTTP_LUA_CONTEXT_CONTENT
| NGX_HTTP_LUA_CONTEXT_TIMER);

lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
mt = lmcf->lua;
Expand Down Expand Up @@ -142,7 +143,8 @@ ngx_http_lua_coroutine_resume(lua_State *L)

ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
| NGX_HTTP_LUA_CONTEXT_ACCESS
| NGX_HTTP_LUA_CONTEXT_CONTENT);
| NGX_HTTP_LUA_CONTEXT_CONTENT
| NGX_HTTP_LUA_CONTEXT_TIMER);

p_coctx = ctx->cur_co_ctx;
if (p_coctx == NULL) {
Expand Down Expand Up @@ -204,7 +206,8 @@ ngx_http_lua_coroutine_yield(lua_State *L)

ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
| NGX_HTTP_LUA_CONTEXT_ACCESS
| NGX_HTTP_LUA_CONTEXT_CONTENT);
| NGX_HTTP_LUA_CONTEXT_CONTENT
| NGX_HTTP_LUA_CONTEXT_TIMER);

coctx = ctx->cur_co_ctx;

Expand Down Expand Up @@ -323,7 +326,8 @@ ngx_http_lua_coroutine_status(lua_State *L)

ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
| NGX_HTTP_LUA_CONTEXT_ACCESS
| NGX_HTTP_LUA_CONTEXT_CONTENT);
| NGX_HTTP_LUA_CONTEXT_CONTENT
| NGX_HTTP_LUA_CONTEXT_TIMER);

coctx = ngx_http_lua_get_co_ctx(co, ctx);
if (coctx == NULL) {
Expand Down
15 changes: 15 additions & 0 deletions src/ngx_http_lua_headers.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ ngx_http_lua_ngx_req_http_version(lua_State *L)
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

switch (r->http_version) {
case NGX_HTTP_VERSION_9:
lua_pushnumber(L, 0.9);
Expand Down Expand Up @@ -91,6 +93,8 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L)
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

hc = r->main->http_connection;

if (hc->nbusy) {
Expand Down Expand Up @@ -277,6 +281,8 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L) {
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

lua_createtable(L, 0, 4);

if (!raw) {
Expand Down Expand Up @@ -352,6 +358,8 @@ ngx_http_lua_ngx_header_get(lua_State *L)
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

/* we skip the first argument that is the table */
p = (u_char *) luaL_checklstring(L, 2, &len);

Expand Down Expand Up @@ -407,6 +415,11 @@ ngx_http_lua_ngx_header_set(lua_State *L)
}

ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
if (ctx == NULL) {
return luaL_error(L, "no ctx");
}

ngx_http_lua_check_fake_request2(L, r, ctx);

if (ctx->headers_sent) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "attempt to "
Expand Down Expand Up @@ -562,6 +575,8 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L)
return luaL_error(L, "no request object found");
}

ngx_http_lua_check_fake_request(L, r);

p = (u_char *) luaL_checklstring(L, 1, &len);

dd("key: %.*s, len %d", (int) len, p, (int) len);
Expand Down
8 changes: 8 additions & 0 deletions src/ngx_http_lua_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ ngx_http_lua_ngx_get(lua_State *L)
if (len == sizeof("status") - 1
&& ngx_strncmp(p, "status", sizeof("status") - 1) == 0)
{
ngx_http_lua_check_fake_request(L, r);
lua_pushnumber(L, (lua_Number) r->headers_out.status);
return 1;
}
Expand All @@ -78,6 +79,11 @@ ngx_http_lua_ngx_get(lua_State *L)
&& ngx_strncmp(p, "headers_sent", sizeof("headers_sent") - 1) == 0)
{
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
if (ctx == NULL) {
return luaL_error(L, "no ctx");
}

ngx_http_lua_check_fake_request2(L, r, ctx);

dd("headers sent: %d", ctx->headers_sent);

Expand Down Expand Up @@ -124,6 +130,8 @@ ngx_http_lua_ngx_set(lua_State *L)
return 0;
}

ngx_http_lua_check_fake_request2(L, r, ctx);

/* get the value */
r->headers_out.status = (ngx_uint_t) luaL_checknumber(L, 3);
return 0;
Expand Down
28 changes: 27 additions & 1 deletion src/ngx_http_lua_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ static ngx_conf_post_t ngx_http_lua_lowat_post =

static ngx_command_t ngx_http_lua_cmds[] = {

{ ngx_string("lua_max_running_timers"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(ngx_http_lua_main_conf_t, max_running_timers),
NULL },

{ ngx_string("lua_max_pending_timers"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(ngx_http_lua_main_conf_t, max_pending_timers),
NULL },

{ ngx_string("lua_shared_dict"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
ngx_http_lua_shared_dict,
Expand Down Expand Up @@ -489,6 +503,8 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf)
* lmcf->lua = NULL;
* lmcf->lua_path = { 0, NULL };
* lmcf->lua_cpath = { 0, NULL };
* lmcf->pending_timers = 0;
* lmcf->running_timers = 0;
* lmcf->regex_cache_entries = 0;
* lmcf->shm_zones = NULL;
* lmcf->init_handler = NULL;
Expand All @@ -505,6 +521,8 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf)
*/

lmcf->pool = cf->pool;
lmcf->max_pending_timers = NGX_CONF_UNSET;
lmcf->max_running_timers = NGX_CONF_UNSET;
#if (NGX_PCRE)
lmcf->regex_cache_max_entries = NGX_CONF_UNSET;
#endif
Expand All @@ -519,14 +537,22 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf)
static char *
ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf)
{
#if (NGX_PCRE)
ngx_http_lua_main_conf_t *lmcf = conf;

#if (NGX_PCRE)
if (lmcf->regex_cache_max_entries == NGX_CONF_UNSET) {
lmcf->regex_cache_max_entries = 1024;
}
#endif

if (lmcf->max_pending_timers == NGX_CONF_UNSET) {
lmcf->max_pending_timers = 1024;
}

if (lmcf->max_running_timers == NGX_CONF_UNSET) {
lmcf->max_running_timers = 256;
}

return NGX_CONF_OK;
}

Expand Down
Loading

0 comments on commit 2ac8d89

Please sign in to comment.