Skip to content

Commit 393c954

Browse files
rainingmasterletianjinhua.tan
authored
feature: added exit_worker_by* to run Lua code upon nginx worker process exit. (#1682)
Co-authored-by: letian <[email protected]> Co-authored-by: jinhua.tan <[email protected]>
1 parent 1669904 commit 393c954

14 files changed

+681
-73
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ install:
8383
- git clone https://github.com/openresty/rds-json-nginx-module.git ../rds-json-nginx-module
8484
- git clone https://github.com/openresty/srcache-nginx-module.git ../srcache-nginx-module
8585
- git clone https://github.com/openresty/redis2-nginx-module.git ../redis2-nginx-module
86-
- git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core
86+
- git clone -b exit_worker https://github.com/rainingmaster/lua-resty-core.git ../lua-resty-core
8787
- git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
8888
- git clone https://github.com/openresty/lua-resty-mysql.git ../lua-resty-mysql
8989
- git clone https://github.com/openresty/lua-resty-string.git ../lua-resty-string

README.markdown

Lines changed: 80 additions & 35 deletions
Large diffs are not rendered by default.

config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ HTTP_LUA_SRCS=" \
278278
$ngx_addon_dir/src/ngx_http_lua_bodyfilterby.c \
279279
$ngx_addon_dir/src/ngx_http_lua_initby.c \
280280
$ngx_addon_dir/src/ngx_http_lua_initworkerby.c \
281+
$ngx_addon_dir/src/ngx_http_lua_exitworkerby.c \
281282
$ngx_addon_dir/src/ngx_http_lua_socket_udp.c \
282283
$ngx_addon_dir/src/ngx_http_lua_req_method.c \
283284
$ngx_addon_dir/src/ngx_http_lua_phase.c \
@@ -339,6 +340,7 @@ HTTP_LUA_DEPS=" \
339340
$ngx_addon_dir/src/ngx_http_lua_bodyfilterby.h \
340341
$ngx_addon_dir/src/ngx_http_lua_initby.h \
341342
$ngx_addon_dir/src/ngx_http_lua_initworkerby.h \
343+
$ngx_addon_dir/src/ngx_http_lua_exitworkerby.h \
342344
$ngx_addon_dir/src/ngx_http_lua_socket_udp.h \
343345
$ngx_addon_dir/src/ngx_http_lua_probe.h \
344346
$ngx_addon_dir/src/ngx_http_lua_uthread.h \

doc/HttpLuaModule.wiki

Lines changed: 71 additions & 35 deletions
Large diffs are not rendered by default.

src/ngx_http_lua_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ typedef struct {
138138
#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400
139139
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800
140140
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000
141+
#define NGX_HTTP_LUA_CONTEXT_EXIT_WORKER 0x2000
141142

142143

143144
#define NGX_HTTP_LUA_FFI_NO_REQ_CTX -100
@@ -226,6 +227,9 @@ struct ngx_http_lua_main_conf_s {
226227
ngx_http_lua_main_conf_handler_pt init_worker_handler;
227228
ngx_str_t init_worker_src;
228229

230+
ngx_http_lua_main_conf_handler_pt exit_worker_handler;
231+
ngx_str_t exit_worker_src;
232+
229233
ngx_http_lua_balancer_peer_data_t *balancer_peer_data;
230234
/* neither yielding nor recursion is possible in
231235
* balancer_by_lua*, so there cannot be any races among

src/ngx_http_lua_directive.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "ngx_http_lua_bodyfilterby.h"
2424
#include "ngx_http_lua_initby.h"
2525
#include "ngx_http_lua_initworkerby.h"
26+
#include "ngx_http_lua_exitworkerby.h"
2627
#include "ngx_http_lua_shdict.h"
2728
#include "ngx_http_lua_ssl_certby.h"
2829
#include "ngx_http_lua_lex.h"
@@ -1200,6 +1201,64 @@ ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
12001201
}
12011202

12021203

1204+
char *
1205+
ngx_http_lua_exit_worker_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
1206+
void *conf)
1207+
{
1208+
char *rv;
1209+
ngx_conf_t save;
1210+
1211+
save = *cf;
1212+
cf->handler = ngx_http_lua_exit_worker_by_lua;
1213+
cf->handler_conf = conf;
1214+
1215+
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
1216+
1217+
*cf = save;
1218+
1219+
return rv;
1220+
}
1221+
1222+
1223+
char *
1224+
ngx_http_lua_exit_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
1225+
void *conf)
1226+
{
1227+
u_char *name;
1228+
ngx_str_t *value;
1229+
ngx_http_lua_main_conf_t *lmcf = conf;
1230+
1231+
/* must specify a content handler */
1232+
if (cmd->post == NULL) {
1233+
return NGX_CONF_ERROR;
1234+
}
1235+
1236+
if (lmcf->exit_worker_handler) {
1237+
return "is duplicate";
1238+
}
1239+
1240+
value = cf->args->elts;
1241+
1242+
lmcf->exit_worker_handler = (ngx_http_lua_main_conf_handler_pt) cmd->post;
1243+
1244+
if (cmd->post == ngx_http_lua_exit_worker_by_file) {
1245+
name = ngx_http_lua_rebase_path(cf->pool, value[1].data,
1246+
value[1].len);
1247+
if (name == NULL) {
1248+
return NGX_CONF_ERROR;
1249+
}
1250+
1251+
lmcf->exit_worker_src.data = name;
1252+
lmcf->exit_worker_src.len = ngx_strlen(name);
1253+
1254+
} else {
1255+
lmcf->exit_worker_src = value[1];
1256+
}
1257+
1258+
return NGX_CONF_OK;
1259+
}
1260+
1261+
12031262
#if defined(NDK) && NDK
12041263
static ngx_int_t
12051264
ngx_http_lua_set_by_lua_init(ngx_http_request_t *r)

src/ngx_http_lua_directive.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ char *ngx_http_lua_init_worker_by_lua_block(ngx_conf_t *cf,
5353
ngx_command_t *cmd, void *conf);
5454
char *ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
5555
void *conf);
56+
char *ngx_http_lua_exit_worker_by_lua_block(ngx_conf_t *cf,
57+
ngx_command_t *cmd, void *conf);
58+
char *ngx_http_lua_exit_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
59+
void *conf);
5660
char *ngx_http_lua_code_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
5761
char *ngx_http_lua_load_resty_core(ngx_conf_t *cf, ngx_command_t *cmd,
5862
void *conf);

src/ngx_http_lua_exitworkerby.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
2+
/*
3+
* Copyright (C) Yichun Zhang (agentzh)
4+
*/
5+
6+
7+
#ifndef DDEBUG
8+
#define DDEBUG 0
9+
#endif
10+
#include "ddebug.h"
11+
12+
13+
#include "ngx_http_lua_exitworkerby.h"
14+
#include "ngx_http_lua_util.h"
15+
16+
17+
void
18+
ngx_http_lua_exit_worker(ngx_cycle_t *cycle)
19+
{
20+
ngx_http_lua_main_conf_t *lmcf;
21+
ngx_connection_t *c = NULL;
22+
ngx_http_request_t *r = NULL;
23+
ngx_http_lua_ctx_t *ctx;
24+
ngx_http_conf_ctx_t *conf_ctx;
25+
26+
lmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_lua_module);
27+
if (lmcf == NULL
28+
|| lmcf->exit_worker_handler == NULL
29+
|| lmcf->lua == NULL
30+
#if !(NGX_WIN32)
31+
|| (ngx_process == NGX_PROCESS_HELPER
32+
# ifdef HAVE_PRIVILEGED_PROCESS_PATCH
33+
&& !ngx_is_privileged_agent
34+
# endif
35+
)
36+
#endif /* NGX_WIN32 */
37+
)
38+
{
39+
return;
40+
}
41+
42+
conf_ctx = ((ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]);
43+
44+
c = ngx_http_lua_create_fake_connection(NULL);
45+
if (c == NULL) {
46+
goto failed;
47+
}
48+
49+
c->log = ngx_cycle->log;
50+
51+
r = ngx_http_lua_create_fake_request(c);
52+
if (r == NULL) {
53+
goto failed;
54+
}
55+
56+
r->main_conf = conf_ctx->main_conf;
57+
r->srv_conf = conf_ctx->srv_conf;
58+
r->loc_conf = conf_ctx->loc_conf;
59+
60+
ctx = ngx_http_lua_create_ctx(r);
61+
if (ctx == NULL) {
62+
goto failed;
63+
}
64+
65+
ctx->context = NGX_HTTP_LUA_CONTEXT_EXIT_WORKER;
66+
ctx->cur_co_ctx = NULL;
67+
68+
ngx_http_lua_set_req(lmcf->lua, r);
69+
70+
(void) lmcf->exit_worker_handler(cycle->log, lmcf, lmcf->lua);
71+
72+
ngx_destroy_pool(c->pool);
73+
return;
74+
75+
failed:
76+
77+
if (c) {
78+
ngx_http_lua_close_fake_connection(c);
79+
}
80+
81+
return;
82+
}
83+
84+
85+
ngx_int_t
86+
ngx_http_lua_exit_worker_by_inline(ngx_log_t *log,
87+
ngx_http_lua_main_conf_t *lmcf, lua_State *L)
88+
{
89+
int status;
90+
91+
status = luaL_loadbuffer(L, (char *) lmcf->exit_worker_src.data,
92+
lmcf->exit_worker_src.len, "=exit_worker_by_lua")
93+
|| ngx_http_lua_do_call(log, L);
94+
95+
return ngx_http_lua_report(log, L, status, "exit_worker_by_lua");
96+
}
97+
98+
99+
ngx_int_t
100+
ngx_http_lua_exit_worker_by_file(ngx_log_t *log, ngx_http_lua_main_conf_t *lmcf,
101+
lua_State *L)
102+
{
103+
int status;
104+
105+
status = luaL_loadfile(L, (char *) lmcf->exit_worker_src.data)
106+
|| ngx_http_lua_do_call(log, L);
107+
108+
return ngx_http_lua_report(log, L, status, "exit_worker_by_lua_file");
109+
}
110+
111+
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

src/ngx_http_lua_exitworkerby.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
/*
3+
* Copyright (C) Yichun Zhang (agentzh)
4+
*/
5+
6+
7+
#ifndef _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDED_
8+
#define _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDED_
9+
10+
11+
#include "ngx_http_lua_common.h"
12+
13+
14+
ngx_int_t ngx_http_lua_exit_worker_by_inline(ngx_log_t *log,
15+
ngx_http_lua_main_conf_t *lmcf, lua_State *L);
16+
17+
ngx_int_t ngx_http_lua_exit_worker_by_file(ngx_log_t *log,
18+
ngx_http_lua_main_conf_t *lmcf, lua_State *L);
19+
20+
void ngx_http_lua_exit_worker(ngx_cycle_t *cycle);
21+
22+
23+
#endif /* _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDED_ */
24+
25+
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

src/ngx_http_lua_module.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "ngx_http_lua_bodyfilterby.h"
2323
#include "ngx_http_lua_initby.h"
2424
#include "ngx_http_lua_initworkerby.h"
25+
#include "ngx_http_lua_exitworkerby.h"
2526
#include "ngx_http_lua_probe.h"
2627
#include "ngx_http_lua_semaphore.h"
2728
#include "ngx_http_lua_balancer.h"
@@ -229,6 +230,20 @@ static ngx_command_t ngx_http_lua_cmds[] = {
229230
0,
230231
(void *) ngx_http_lua_init_worker_by_file },
231232

233+
{ ngx_string("exit_worker_by_lua_block"),
234+
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
235+
ngx_http_lua_exit_worker_by_lua_block,
236+
NGX_HTTP_MAIN_CONF_OFFSET,
237+
0,
238+
(void *) ngx_http_lua_exit_worker_by_inline },
239+
240+
{ ngx_string("exit_worker_by_lua_file"),
241+
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
242+
ngx_http_lua_exit_worker_by_lua,
243+
NGX_HTTP_MAIN_CONF_OFFSET,
244+
0,
245+
(void *) ngx_http_lua_exit_worker_by_file },
246+
232247
#if defined(NDK) && NDK
233248
/* set_by_lua_block $res { inline Lua code } */
234249
{ ngx_string("set_by_lua_block"),
@@ -636,7 +651,7 @@ ngx_module_t ngx_http_lua_module = {
636651
ngx_http_lua_init_worker, /* init process */
637652
NULL, /* init thread */
638653
NULL, /* exit thread */
639-
NULL, /* exit process */
654+
ngx_http_lua_exit_worker, /* exit process */
640655
NULL, /* exit master */
641656
NGX_MODULE_V1_PADDING
642657
};

src/ngx_http_lua_util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
: (c) == NGX_HTTP_LUA_CONTEXT_BODY_FILTER ? "body_filter_by_lua*" \
5454
: (c) == NGX_HTTP_LUA_CONTEXT_TIMER ? "ngx.timer" \
5555
: (c) == NGX_HTTP_LUA_CONTEXT_INIT_WORKER ? "init_worker_by_lua*" \
56+
: (c) == NGX_HTTP_LUA_CONTEXT_EXIT_WORKER ? "exit_worker_by_lua*" \
5657
: (c) == NGX_HTTP_LUA_CONTEXT_BALANCER ? "balancer_by_lua*" \
5758
: (c) == NGX_HTTP_LUA_CONTEXT_SSL_CERT ? "ssl_certificate_by_lua*" \
5859
: (c) == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE ? \

t/089-phase.t

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ log_level('warn');
88

99
repeat_each(2);
1010

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

1313
#no_diff();
1414
#no_long_string();
@@ -176,3 +176,28 @@ GET /lua
176176
init_worker
177177
--- no_error_log
178178
[error]
179+
180+
181+
182+
=== TEST 11: get_phase in exit_worker_by_lua
183+
--- http_config
184+
exit_worker_by_lua_block {
185+
local phase = ngx.get_phase()
186+
ngx.log(ngx.ERR, phase)
187+
ngx.log(ngx.ERR, "exiting now")
188+
}
189+
--- config
190+
location /lua {
191+
content_by_lua_block {
192+
ngx.say("ok")
193+
}
194+
}
195+
--- request
196+
GET /lua
197+
--- response_body
198+
ok
199+
--- shutdown_error_log eval
200+
[
201+
qr/exit_worker_by_lua:\d+: exit_worker/,
202+
qr/exiting now$/,
203+
]

0 commit comments

Comments
 (0)