Hi! It's a good design. It seems the worker process is not killed until expired, the time is set by 'worker_shutdown_timeout'. But I think ngx_shutdown_timer_handler will never be called, because of the following deal.
if (ngx_exiting) { if (ngx_event_no_timers_left() == NGX_OK) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); ngx_worker_process_exit(cycle); // the worker process exits though there are cancelable timers such as ngx_shutdown_event. } } I'm not sure it's right? diff -r d45072375572 src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Tue Mar 07 18:51:17 2017 +0300 +++ b/src/core/ngx_cycle.c Sun Mar 05 17:03:22 2017 +0800 @@ -1348,7 +1348,6 @@ ngx_shutdown_event.handler = ngx_shutdown_timer_handler; ngx_shutdown_event.data = cycle; ngx_shutdown_event.log = cycle->log; - ngx_shutdown_event.cancelable = 1; ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout); } And I think it's better that the shutting down process keep alive until ' worker_shutdown_timeout'. Thanks. B.R. 2017-03-08 1:01 GMT+08:00 Maxim Dounin <mdou...@mdounin.ru>: > details: http://hg.nginx.org/nginx/rev/97c99bb43737 > branches: > changeset: 6930:97c99bb43737 > user: Maxim Dounin <mdou...@mdounin.ru> > date: Tue Mar 07 18:51:16 2017 +0300 > description: > Introduced worker_shutdown_timeout. > > The directive configures a timeout to be used when gracefully shutting down > worker processes. When the timer expires, nginx will try to close all > the connections currently open to facilitate shutdown. > > diffstat: > > src/core/nginx.c | 9 ++++++ > src/core/ngx_cycle.c | 53 ++++++++++++++++++++++++++++++ > ++++++++++ > src/core/ngx_cycle.h | 2 + > src/os/unix/ngx_process_cycle.c | 1 + > src/os/win32/ngx_process_cycle.c | 1 + > 5 files changed, 66 insertions(+), 0 deletions(-) > > diffs (148 lines): > > diff --git a/src/core/nginx.c b/src/core/nginx.c > --- a/src/core/nginx.c > +++ b/src/core/nginx.c > @@ -124,6 +124,13 @@ static ngx_command_t ngx_core_commands[ > offsetof(ngx_core_conf_t, rlimit_core), > NULL }, > > + { ngx_string("worker_shutdown_timeout"), > + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, > + ngx_conf_set_msec_slot, > + 0, > + offsetof(ngx_core_conf_t, shutdown_timeout), > + NULL }, > + > { ngx_string("working_directory"), > NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, > ngx_conf_set_str_slot, > @@ -1014,6 +1021,7 @@ ngx_core_module_create_conf(ngx_cycle_t > ccf->daemon = NGX_CONF_UNSET; > ccf->master = NGX_CONF_UNSET; > ccf->timer_resolution = NGX_CONF_UNSET_MSEC; > + ccf->shutdown_timeout = NGX_CONF_UNSET_MSEC; > > ccf->worker_processes = NGX_CONF_UNSET; > ccf->debug_points = NGX_CONF_UNSET; > @@ -1042,6 +1050,7 @@ ngx_core_module_init_conf(ngx_cycle_t *c > ngx_conf_init_value(ccf->daemon, 1); > ngx_conf_init_value(ccf->master, 1); > ngx_conf_init_msec_value(ccf->timer_resolution, 0); > + ngx_conf_init_msec_value(ccf->shutdown_timeout, 0); > > ngx_conf_init_value(ccf->worker_processes, 1); > ngx_conf_init_value(ccf->debug_points, 0); > diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c > --- a/src/core/ngx_cycle.c > +++ b/src/core/ngx_cycle.c > @@ -15,6 +15,7 @@ static ngx_int_t ngx_init_zone_pool(ngx_ > ngx_shm_zone_t *shm_zone); > static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); > static void ngx_clean_old_cycles(ngx_event_t *ev); > +static void ngx_shutdown_timer_handler(ngx_event_t *ev); > > > volatile ngx_cycle_t *ngx_cycle; > @@ -22,6 +23,7 @@ ngx_array_t ngx_old_cycles; > > static ngx_pool_t *ngx_temp_pool; > static ngx_event_t ngx_cleaner_event; > +static ngx_event_t ngx_shutdown_event; > > ngx_uint_t ngx_test_config; > ngx_uint_t ngx_dump_config; > @@ -1333,3 +1335,54 @@ ngx_clean_old_cycles(ngx_event_t *ev) > ngx_old_cycles.nelts = 0; > } > } > + > + > +void > +ngx_set_shutdown_timer(ngx_cycle_t *cycle) > +{ > + ngx_core_conf_t *ccf; > + > + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, > ngx_core_module); > + > + if (ccf->shutdown_timeout) { > + ngx_shutdown_event.handler = ngx_shutdown_timer_handler; > + ngx_shutdown_event.data = cycle; > + ngx_shutdown_event.log = cycle->log; > + ngx_shutdown_event.cancelable = 1; > + > + ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout); > + } > +} > + > + > +static void > +ngx_shutdown_timer_handler(ngx_event_t *ev) > +{ > + ngx_uint_t i; > + ngx_cycle_t *cycle; > + ngx_connection_t *c; > + > + cycle = ev->data; > + > + c = cycle->connections; > + > + for (i = 0; i < cycle->connection_n; i++) { > + > + if (c[i].fd == (ngx_socket_t) -1 > + || c[i].read == NULL > + || c[i].read->accept > + || c[i].read->channel > + || c[i].read->resolver) > + { > + continue; > + } > + > + ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, > + "*%uA shutdown timeout", c[i].number); > + > + c[i].close = 1; > + c[i].error = 1; > + > + c[i].read->handler(c[i].read); > + } > +} > diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h > --- a/src/core/ngx_cycle.h > +++ b/src/core/ngx_cycle.h > @@ -88,6 +88,7 @@ typedef struct { > ngx_flag_t master; > > ngx_msec_t timer_resolution; > + ngx_msec_t shutdown_timeout; > > ngx_int_t worker_processes; > ngx_int_t debug_points; > @@ -129,6 +130,7 @@ ngx_pid_t ngx_exec_new_binary(ngx_cycle_ > ngx_cpuset_t *ngx_get_cpu_affinity(ngx_uint_t n); > ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, > size_t size, void *tag); > +void ngx_set_shutdown_timer(ngx_cycle_t *cycle); > > > extern volatile ngx_cycle_t *ngx_cycle; > diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_ > cycle.c > --- a/src/os/unix/ngx_process_cycle.c > +++ b/src/os/unix/ngx_process_cycle.c > @@ -763,6 +763,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cy > > if (!ngx_exiting) { > ngx_exiting = 1; > + ngx_set_shutdown_timer(cycle); > ngx_close_listening_sockets(cycle); > ngx_close_idle_connections(cycle); > } > diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_ > cycle.c > --- a/src/os/win32/ngx_process_cycle.c > +++ b/src/os/win32/ngx_process_cycle.c > @@ -800,6 +800,7 @@ ngx_worker_thread(void *data) > > if (!ngx_exiting) { > ngx_exiting = 1; > + ngx_set_shutdown_timer(cycle); > ngx_close_listening_sockets(cycle); > ngx_close_idle_connections(cycle); > } > _______________________________________________ > nginx-devel mailing list > nginx-devel@nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel >
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel