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 7 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:** *exitting-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* create resources, To prevent the worker exit abnormal

For instance,

```nginx

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

[Back to TOC](#directives)

exit_worker_by_lua_block
Copy link
Member

Choose a reason for hiding this comment

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

Typo? Should be _by_lua_file here instead, right?

Copy link
Author

Choose a reason for hiding this comment

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

My mistake.

------------------------

**syntax:** *exit_worker_by_lua_file <lua-file-path>*

**context:** *http*

**phase:** *exitting-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
3 changes: 3 additions & 0 deletions src/ngx_http_lua_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,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
60 changes: 60 additions & 0 deletions src/ngx_http_lua_exitworkerby.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

/*
* 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;

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;
}

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

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
52 changes: 52 additions & 0 deletions t/151-exit-worker.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:

use Test::Nginx::Socket::Lua;

repeat_each(1);

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

#log_level("warn");
no_long_string();

run_tests();

__DATA__

=== TEST 1: simple exit_worker_by_lua_block
--- http_config
exit_worker_by_lua_block {
ngx.log(ngx.NOTICE, "log from exit_worker_by_lua_block")
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to confirm if the log is output

Copy link
Author

Choose a reason for hiding this comment

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

i fix 151-exit-worker.t base on iresty/test-nginx and commited.

Copy link
Member

Choose a reason for hiding this comment

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

@lixianliang Apparently iresty/test-nginx is a fork and does not count here :) That feature needs to be merged into the official test-nginx repo before this can be merged otherwise the Travis CI would be failing.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, Now i use offical test-nginx.

}
--- config
location /t {
echo "ok";
}
--- request
GET /t
--- response_body
ok
--- stop_after_request
--- error_log
log from exit_worker_by_lua_block



=== TEST 2: simple exit_worker_by_lua_file
--- http_config
exit_worker_by_lua_file html/exit_worker.lua;
--- config
location /t {
echo "ok";
}
--- user_files
>>> exit_worker.lua
ngx.log(ngx.NOTICE, "log from exit_worker_by_lua_file")
--- request
GET /t
--- response_body
ok
--- stop_after_request
--- error_log
Copy link
Member

Choose a reason for hiding this comment

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

We need to add a --- shutdown_error_log section instead of abusing the request-time --- error_log directive and the hacky --- stop_after_request section IMHO :)

Copy link
Author

Choose a reason for hiding this comment

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

This test cast i update util has shutdown_error_log.

log from exit_worker_by_lua_file