Skip to content

Commit

Permalink
feature: added exit_worker_by* to run Lua code upon nginx worker proc…
Browse files Browse the repository at this point in the history
…ess exit. (openresty#1682)

Co-authored-by: letian <[email protected]>
Co-authored-by: jinhua.tan <[email protected]>
  • Loading branch information
3 people authored Jul 23, 2020
1 parent 1669904 commit 393c954
Show file tree
Hide file tree
Showing 14 changed files with 681 additions and 73 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ install:
- git clone https://github.com/openresty/rds-json-nginx-module.git ../rds-json-nginx-module
- git clone https://github.com/openresty/srcache-nginx-module.git ../srcache-nginx-module
- git clone https://github.com/openresty/redis2-nginx-module.git ../redis2-nginx-module
- git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core
- git clone -b exit_worker https://github.com/rainingmaster/lua-resty-core.git ../lua-resty-core
- git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
- git clone https://github.com/openresty/lua-resty-mysql.git ../lua-resty-mysql
- git clone https://github.com/openresty/lua-resty-string.git ../lua-resty-string
Expand Down
115 changes: 80 additions & 35 deletions README.markdown

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ HTTP_LUA_SRCS=" \
$ngx_addon_dir/src/ngx_http_lua_bodyfilterby.c \
$ngx_addon_dir/src/ngx_http_lua_initby.c \
$ngx_addon_dir/src/ngx_http_lua_initworkerby.c \
$ngx_addon_dir/src/ngx_http_lua_exitworkerby.c \
$ngx_addon_dir/src/ngx_http_lua_socket_udp.c \
$ngx_addon_dir/src/ngx_http_lua_req_method.c \
$ngx_addon_dir/src/ngx_http_lua_phase.c \
Expand Down Expand Up @@ -339,6 +340,7 @@ HTTP_LUA_DEPS=" \
$ngx_addon_dir/src/ngx_http_lua_bodyfilterby.h \
$ngx_addon_dir/src/ngx_http_lua_initby.h \
$ngx_addon_dir/src/ngx_http_lua_initworkerby.h \
$ngx_addon_dir/src/ngx_http_lua_exitworkerby.h \
$ngx_addon_dir/src/ngx_http_lua_socket_udp.h \
$ngx_addon_dir/src/ngx_http_lua_probe.h \
$ngx_addon_dir/src/ngx_http_lua_uthread.h \
Expand Down
106 changes: 71 additions & 35 deletions doc/HttpLuaModule.wiki

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/ngx_http_lua_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ typedef struct {
#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000
#define NGX_HTTP_LUA_CONTEXT_EXIT_WORKER 0x2000


#define NGX_HTTP_LUA_FFI_NO_REQ_CTX -100
Expand Down Expand Up @@ -226,6 +227,9 @@ struct ngx_http_lua_main_conf_s {
ngx_http_lua_main_conf_handler_pt init_worker_handler;
ngx_str_t init_worker_src;

ngx_http_lua_main_conf_handler_pt exit_worker_handler;
ngx_str_t exit_worker_src;

ngx_http_lua_balancer_peer_data_t *balancer_peer_data;
/* neither yielding nor recursion is possible in
* balancer_by_lua*, so there cannot be any races among
Expand Down
59 changes: 59 additions & 0 deletions src/ngx_http_lua_directive.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "ngx_http_lua_bodyfilterby.h"
#include "ngx_http_lua_initby.h"
#include "ngx_http_lua_initworkerby.h"
#include "ngx_http_lua_exitworkerby.h"
#include "ngx_http_lua_shdict.h"
#include "ngx_http_lua_ssl_certby.h"
#include "ngx_http_lua_lex.h"
Expand Down Expand Up @@ -1200,6 +1201,64 @@ ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
}


char *
ngx_http_lua_exit_worker_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
char *rv;
ngx_conf_t save;

save = *cf;
cf->handler = ngx_http_lua_exit_worker_by_lua;
cf->handler_conf = conf;

rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);

*cf = save;

return rv;
}


char *
ngx_http_lua_exit_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
u_char *name;
ngx_str_t *value;
ngx_http_lua_main_conf_t *lmcf = conf;

/* must specify a content handler */
if (cmd->post == NULL) {
return NGX_CONF_ERROR;
}

if (lmcf->exit_worker_handler) {
return "is duplicate";
}

value = cf->args->elts;

lmcf->exit_worker_handler = (ngx_http_lua_main_conf_handler_pt) cmd->post;

if (cmd->post == ngx_http_lua_exit_worker_by_file) {
name = ngx_http_lua_rebase_path(cf->pool, value[1].data,
value[1].len);
if (name == NULL) {
return NGX_CONF_ERROR;
}

lmcf->exit_worker_src.data = name;
lmcf->exit_worker_src.len = ngx_strlen(name);

} else {
lmcf->exit_worker_src = value[1];
}

return NGX_CONF_OK;
}


#if defined(NDK) && NDK
static ngx_int_t
ngx_http_lua_set_by_lua_init(ngx_http_request_t *r)
Expand Down
4 changes: 4 additions & 0 deletions src/ngx_http_lua_directive.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ char *ngx_http_lua_init_worker_by_lua_block(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
char *ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
char *ngx_http_lua_exit_worker_by_lua_block(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
char *ngx_http_lua_exit_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
char *ngx_http_lua_code_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_http_lua_load_resty_core(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
Expand Down
111 changes: 111 additions & 0 deletions src/ngx_http_lua_exitworkerby.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@

/*
* Copyright (C) Yichun Zhang (agentzh)
*/


#ifndef DDEBUG
#define DDEBUG 0
#endif
#include "ddebug.h"


#include "ngx_http_lua_exitworkerby.h"
#include "ngx_http_lua_util.h"


void
ngx_http_lua_exit_worker(ngx_cycle_t *cycle)
{
ngx_http_lua_main_conf_t *lmcf;
ngx_connection_t *c = NULL;
ngx_http_request_t *r = NULL;
ngx_http_lua_ctx_t *ctx;
ngx_http_conf_ctx_t *conf_ctx;

lmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_lua_module);
if (lmcf == NULL
|| lmcf->exit_worker_handler == NULL
|| lmcf->lua == NULL
#if !(NGX_WIN32)
|| (ngx_process == NGX_PROCESS_HELPER
# ifdef HAVE_PRIVILEGED_PROCESS_PATCH
&& !ngx_is_privileged_agent
# endif
)
#endif /* NGX_WIN32 */
)
{
return;
}

conf_ctx = ((ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]);

c = ngx_http_lua_create_fake_connection(NULL);
if (c == NULL) {
goto failed;
}

c->log = ngx_cycle->log;

r = ngx_http_lua_create_fake_request(c);
if (r == NULL) {
goto failed;
}

r->main_conf = conf_ctx->main_conf;
r->srv_conf = conf_ctx->srv_conf;
r->loc_conf = conf_ctx->loc_conf;

ctx = ngx_http_lua_create_ctx(r);
if (ctx == NULL) {
goto failed;
}

ctx->context = NGX_HTTP_LUA_CONTEXT_EXIT_WORKER;
ctx->cur_co_ctx = NULL;

ngx_http_lua_set_req(lmcf->lua, r);

(void) lmcf->exit_worker_handler(cycle->log, lmcf, lmcf->lua);

ngx_destroy_pool(c->pool);
return;

failed:

if (c) {
ngx_http_lua_close_fake_connection(c);
}

return;
}


ngx_int_t
ngx_http_lua_exit_worker_by_inline(ngx_log_t *log,
ngx_http_lua_main_conf_t *lmcf, lua_State *L)
{
int status;

status = luaL_loadbuffer(L, (char *) lmcf->exit_worker_src.data,
lmcf->exit_worker_src.len, "=exit_worker_by_lua")
|| ngx_http_lua_do_call(log, L);

return ngx_http_lua_report(log, L, status, "exit_worker_by_lua");
}


ngx_int_t
ngx_http_lua_exit_worker_by_file(ngx_log_t *log, ngx_http_lua_main_conf_t *lmcf,
lua_State *L)
{
int status;

status = luaL_loadfile(L, (char *) lmcf->exit_worker_src.data)
|| ngx_http_lua_do_call(log, L);

return ngx_http_lua_report(log, L, status, "exit_worker_by_lua_file");
}

/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
25 changes: 25 additions & 0 deletions src/ngx_http_lua_exitworkerby.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

/*
* Copyright (C) Yichun Zhang (agentzh)
*/


#ifndef _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDED_
#define _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDED_


#include "ngx_http_lua_common.h"


ngx_int_t ngx_http_lua_exit_worker_by_inline(ngx_log_t *log,
ngx_http_lua_main_conf_t *lmcf, lua_State *L);

ngx_int_t ngx_http_lua_exit_worker_by_file(ngx_log_t *log,
ngx_http_lua_main_conf_t *lmcf, lua_State *L);

void ngx_http_lua_exit_worker(ngx_cycle_t *cycle);


#endif /* _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDED_ */

/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
17 changes: 16 additions & 1 deletion src/ngx_http_lua_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "ngx_http_lua_bodyfilterby.h"
#include "ngx_http_lua_initby.h"
#include "ngx_http_lua_initworkerby.h"
#include "ngx_http_lua_exitworkerby.h"
#include "ngx_http_lua_probe.h"
#include "ngx_http_lua_semaphore.h"
#include "ngx_http_lua_balancer.h"
Expand Down Expand Up @@ -229,6 +230,20 @@ static ngx_command_t ngx_http_lua_cmds[] = {
0,
(void *) ngx_http_lua_init_worker_by_file },

{ ngx_string("exit_worker_by_lua_block"),
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_http_lua_exit_worker_by_lua_block,
NGX_HTTP_MAIN_CONF_OFFSET,
0,
(void *) ngx_http_lua_exit_worker_by_inline },

{ ngx_string("exit_worker_by_lua_file"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_http_lua_exit_worker_by_lua,
NGX_HTTP_MAIN_CONF_OFFSET,
0,
(void *) ngx_http_lua_exit_worker_by_file },

#if defined(NDK) && NDK
/* set_by_lua_block $res { inline Lua code } */
{ ngx_string("set_by_lua_block"),
Expand Down Expand Up @@ -636,7 +651,7 @@ ngx_module_t ngx_http_lua_module = {
ngx_http_lua_init_worker, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
ngx_http_lua_exit_worker, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
Expand Down
1 change: 1 addition & 0 deletions src/ngx_http_lua_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
: (c) == NGX_HTTP_LUA_CONTEXT_BODY_FILTER ? "body_filter_by_lua*" \
: (c) == NGX_HTTP_LUA_CONTEXT_TIMER ? "ngx.timer" \
: (c) == NGX_HTTP_LUA_CONTEXT_INIT_WORKER ? "init_worker_by_lua*" \
: (c) == NGX_HTTP_LUA_CONTEXT_EXIT_WORKER ? "exit_worker_by_lua*" \
: (c) == NGX_HTTP_LUA_CONTEXT_BALANCER ? "balancer_by_lua*" \
: (c) == NGX_HTTP_LUA_CONTEXT_SSL_CERT ? "ssl_certificate_by_lua*" \
: (c) == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE ? \
Expand Down
27 changes: 26 additions & 1 deletion t/089-phase.t
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ log_level('warn');

repeat_each(2);

plan tests => repeat_each() * (blocks() * 2 + 1);
plan tests => repeat_each() * (blocks() * 2 + 2);

#no_diff();
#no_long_string();
Expand Down Expand Up @@ -176,3 +176,28 @@ GET /lua
init_worker
--- no_error_log
[error]



=== TEST 11: get_phase in exit_worker_by_lua
--- http_config
exit_worker_by_lua_block {
local phase = ngx.get_phase()
ngx.log(ngx.ERR, phase)
ngx.log(ngx.ERR, "exiting now")
}
--- config
location /lua {
content_by_lua_block {
ngx.say("ok")
}
}
--- request
GET /lua
--- response_body
ok
--- shutdown_error_log eval
[
qr/exit_worker_by_lua:\d+: exit_worker/,
qr/exiting now$/,
]
Loading

0 comments on commit 393c954

Please sign in to comment.