commit eba3948: [Rework] Another phase of finish actions rework
Vsevolod Stakhov
vsevolod at highsecure.ru
Thu Nov 7 14:49:09 UTC 2019
Author: Vsevolod Stakhov
Date: 2019-11-07 14:44:45 +0000
URL: https://github.com/rspamd/rspamd/commit/eba3948ce08b642945ca02942d9c391a5a13d8f4
[Rework] Another phase of finish actions rework
---
src/libserver/worker_util.c | 99 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 75 insertions(+), 24 deletions(-)
diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c
index 63342a72a..e3927063d 100644
--- a/src/libserver/worker_util.c
+++ b/src/libserver/worker_util.c
@@ -184,29 +184,33 @@ rspamd_worker_terminate_handlers (struct rspamd_worker *w)
return;
}
- else if (w->nconns > 0) {
- /*
- * Wait until all connections are terminated
- */
- w->state = rspamd_worker_wait_connections;
- }
else {
- /*
- * Start finish scripts
- */
- w->state = rspamd_worker_wait_final_scripts;
- msg_info ("performing finishing actions");
-
- if ((w->flags & RSPAMD_WORKER_SCANNER) &&
- rspamd_worker_call_finish_handlers (w)) {
- w->state = rspamd_worker_wait_final_scripts;
+ if (w->nconns > 0) {
+ /*
+ * Wait until all connections are terminated
+ */
+ w->state = rspamd_worker_wait_connections;
}
else {
/*
- * We are done now
+ * Start finish scripts
*/
- ev_break (actx->event_loop, EVBREAK_ALL);
- w->state = rspamd_worker_wanna_die;
+ if (w->state != rspamd_worker_wait_final_scripts) {
+ w->state = rspamd_worker_wait_final_scripts;
+ msg_info ("performing finishing actions");
+
+ if ((w->flags & RSPAMD_WORKER_SCANNER) &&
+ rspamd_worker_call_finish_handlers (w)) {
+ w->state = rspamd_worker_wait_final_scripts;
+ }
+ else {
+ /*
+ * We are done now
+ */
+ ev_break (actx->event_loop, EVBREAK_ALL);
+ w->state = rspamd_worker_wanna_die;
+ }
+ }
}
}
}
@@ -214,12 +218,34 @@ rspamd_worker_terminate_handlers (struct rspamd_worker *w)
static void
rspamd_worker_on_delayed_shutdown (EV_P_ ev_timer *w, int revents)
{
+ struct rspamd_worker *worker = (struct rspamd_worker *)w->data;
+
+ worker->state = rspamd_worker_wanna_die;
+ ev_timer_stop (EV_A_ w);
ev_break (loop, EVBREAK_ALL);
#ifdef WITH_GPERF_TOOLS
ProfilerStop ();
#endif
}
+static void
+rspamd_worker_shutdown_check (EV_P_ ev_timer *w, int revents)
+{
+ struct rspamd_worker *worker = (struct rspamd_worker *)w->data;
+
+ if (worker->state != rspamd_worker_wanna_die) {
+ ev_timer_again (EV_A_ w);
+ rspamd_worker_terminate_handlers (worker);
+
+ if (worker->state == rspamd_worker_wanna_die) {
+ ev_timer_stop (EV_A_ w);
+ }
+ }
+ else {
+ ev_timer_stop (EV_A_ w);
+ }
+}
+
/*
* Config reload is designed by sending sigusr2 to active workers and pending shutdown of them
*/
@@ -228,7 +254,7 @@ rspamd_worker_usr2_handler (struct rspamd_worker_signal_handler *sigh, void *arg
{
/* Do not accept new connections, preparing to end worker's process */
if (sigh->worker->state == rspamd_worker_state_running) {
- static ev_timer shutdown_ev;
+ static ev_timer shutdown_ev, shutdown_check_ev;
ev_tstamp shutdown_ts;
shutdown_ts = MAX (SOFT_SHUTDOWN_TIME,
@@ -243,9 +269,18 @@ rspamd_worker_usr2_handler (struct rspamd_worker_signal_handler *sigh, void *arg
G_STRFUNC,
"worker's shutdown is pending in %.2f sec",
shutdown_ts);
+
+ /* Soft shutdown timer */
+ shutdown_ev.data = sigh->worker;
ev_timer_init (&shutdown_ev, rspamd_worker_on_delayed_shutdown,
shutdown_ts, 0.0);
ev_timer_start (sigh->event_loop, &shutdown_ev);
+
+ /* This timer checks if we are ready to die and is called frequently */
+ shutdown_check_ev.data = sigh->worker;
+ ev_timer_init (&shutdown_check_ev, rspamd_worker_shutdown_check,
+ 0.5, 0.5);
+ ev_timer_start (sigh->event_loop, &shutdown_check_ev);
rspamd_worker_stop_accept (sigh->worker);
}
@@ -272,7 +307,11 @@ static gboolean
rspamd_worker_term_handler (struct rspamd_worker_signal_handler *sigh, void *arg)
{
if (sigh->worker->state == rspamd_worker_state_running) {
- static ev_timer shutdown_ev;
+ static ev_timer shutdown_ev, shutdown_check_ev;
+ ev_tstamp shutdown_ts;
+
+ shutdown_ts = MAX (SOFT_SHUTDOWN_TIME,
+ sigh->worker->srv->cfg->task_timeout * 2.0);
rspamd_worker_ignore_signal (sigh);
sigh->worker->state = rspamd_worker_state_terminating;
@@ -283,11 +322,23 @@ rspamd_worker_term_handler (struct rspamd_worker_signal_handler *sigh, void *arg
"terminating after receiving signal %s",
g_strsignal (sigh->signo));
- rspamd_worker_terminate_handlers (sigh->worker);
- ev_timer_init (&shutdown_ev, rspamd_worker_on_delayed_shutdown,
- 0.0, 0.0);
- ev_timer_start (sigh->event_loop, &shutdown_ev);
rspamd_worker_stop_accept (sigh->worker);
+ rspamd_worker_terminate_handlers (sigh->worker);
+
+ /* Check if we are ready to die */
+ if (sigh->worker->state != rspamd_worker_wanna_die) {
+ /* This timer is called when we have no choices but to die */
+ shutdown_ev.data = sigh->worker;
+ ev_timer_init (&shutdown_ev, rspamd_worker_on_delayed_shutdown,
+ shutdown_ts, 0.0);
+ ev_timer_start (sigh->event_loop, &shutdown_ev);
+
+ /* This timer checks if we are ready to die and is called frequently */
+ shutdown_check_ev.data = sigh->worker;
+ ev_timer_init (&shutdown_check_ev, rspamd_worker_shutdown_check,
+ 0.5, 0.5);
+ ev_timer_start (sigh->event_loop, &shutdown_check_ev);
+ }
}
/* Stop reacting on signals */
More information about the Commits
mailing list