Skip to content

add exit_worker_by* feature #927

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,8 @@ Directives
* [init_worker_by_lua](#init_worker_by_lua)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, this file is automatically generated (you can check out the comment at the beginning of this file).

You should edit doc/HttpLuaModule.wiki file instead and use the ngx-releng tool chain to update this markdown file automatically from the .wiki file.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

* [init_worker_by_lua_block](#init_worker_by_lua_block)
* [init_worker_by_lua_file](#init_worker_by_lua_file)
* [exit_worker_by_lua_block](#exit_worker_by_lua_block)
* [exit_worker_by_lua_file](#exit_worker_by_lua_file)
* [set_by_lua](#set_by_lua)
* [set_by_lua_block](#set_by_lua_block)
* [set_by_lua_file](#set_by_lua_file)
Expand Down Expand Up @@ -1439,6 +1441,43 @@ This directive was first introduced in the `v0.9.5` release.

[Back to TOC](#directives)

exit_worker_by_lua_block
------------------------

**syntax:** *exit_worker_by_lua_block { lua-script }*

**context:** *http*

**phase:** *exiting-worker*

Runs the specified Lua code upon every Nginx worker process's exiting when the master process is enabled.

This hook is often used to release resources when [init_worker_by_lua*](#init_worker_by_lua_block) create resources, To prevent the worker exit abnormal.

For example,

```nginx

exit_worker_by_lua_block {
print("log from exit_worker_by_lua_block")
}
```

[Back to TOC](#directives)

exit_worker_by_lua_file
-----------------------

**syntax:** *exit_worker_by_lua_file { lua--file-path }*

**context:** *http*

**phase:** *exiting-worker*

Similar to [exit_worker_by_lua_block](#exit_worker_by_lua_block), but accepts the file path to a Lua source file or Lua bytecode file.

[Back to TOC](#directives)

set_by_lua
----------

Expand Down
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,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 @@ -406,6 +407,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_req_method.h \
$ngx_addon_dir/src/ngx_http_lua_phase.h \
Expand Down
30 changes: 30 additions & 0 deletions doc/HttpLuaModule.wiki
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,36 @@ Similar to [[#init_worker_by_lua|init_worker_by_lua]], but accepts the file path

This directive was first introduced in the <code>v0.9.5</code> release.

== exit_worker_by_lua_block ==

'''syntax:''' ''exit_worker_by_lua_block { lua-script }''

'''context:''' ''http''

'''phase:''' ''exiting-worker''

Runs the specified Lua code upon every Nginx worker process's exiting when the master process is enabled.

This hook is often used to release resources when [[#init_worker_by_lua_block|init_worker_by_lua*]] create resources, To prevent the worker exit abnormal.

For example,

<geshi lang="nginx">
exit_worker_by_lua_block {
print("log from exit_worker_by_lua_block")
}
</geshi>

== exit_worker_by_lua_file ==

'''syntax:''' ''exit_worker_by_lua_file { lua--file-path }''

'''context:''' ''http''

'''phase:''' ''exiting-worker''

Similar to [[#exit_worker_by_lua_block|exit_worker_by_lua_block]], but accepts the file path to a Lua source file or Lua bytecode file.

== set_by_lua ==

'''syntax:''' ''set_by_lua $res <lua-script-str> [$arg1 $arg2 ...]''
Expand Down
4 changes: 4 additions & 0 deletions src/ngx_http_lua_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,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


#ifndef NGX_LUA_NO_FFI_API
Expand Down Expand Up @@ -185,6 +186,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;
/* balancer_by_lua does not support yielding and
* there cannot be any conflicts among concurrent requests,
Expand Down
61 changes: 61 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 @@ -1208,6 +1209,66 @@ 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;

dd("enter");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better use more meaning use debug message here. people will see this message in the error log when they opened the DDEBUG.


/* 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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: we need a blank line before the } else { line. See other similar places in the existing code base. Thank you!

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 @@ -49,6 +49,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);

#if defined(NDK) && NDK
Expand Down
101 changes: 101 additions & 0 deletions src/ngx_http_lua_exitworkerby.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@

/*
* 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)
{
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_file");
}
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_INCLUDE_
#define _NGX_HTTP_LUA_EXITWORKERBY_H_INCLUDE_


#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_INCLUDE_ */

/* 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 @@ -205,6 +206,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 $res { inline Lua code } [$arg1 [$arg2 [...]]] */
{ ngx_string("set_by_lua_block"),
Expand Down Expand Up @@ -622,7 +637,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
4 changes: 4 additions & 0 deletions src/ngx_http_lua_phase.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ ngx_http_lua_ngx_get_phase(lua_State *L)
lua_pushliteral(L, "ssl_session_fetch");
break;

case NGX_HTTP_LUA_CONTEXT_EXIT_WORKER:
lua_pushliteral(L, "exit_worker");
break;

default:
return luaL_error(L, "unknown phase: %#x", (int) ctx->context);
}
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 @@ -85,6 +85,7 @@ extern char ngx_http_lua_headers_metatable_key;
: (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
Loading