[core] graceful shutdown timeout option

server.feature-flags += ("server.graceful-shutdown-timeout" => 10)

After receiving SIGINT or SIGUSR1, lighttpd will gracefully shutdown,
waiting for existing connections to complete.  In the case of SIGUSR1,
this wait occurs before restarting lighttpd.  The default timeout is
none (unlimited).

When "server.graceful-shutdown-timeout" option is set, it defines the
number of seconds that lighttpd will wait for existing connections to
complete before shutting down the connection.

Sites which expect large uploads or downloads, or those with very slow
clients, might want to set a much longer timeout, e.g 60 seconds

For more immediate graceful restarts, while still allowing existing
connections time to complete, sites should additionally consider
whether or not
  server.feature-flags += ("server.graceful-restart-bg" => "enable")
is appropriate and compatible with their lighttpd.conf settings
personal/stbuehler/tests-path
Glenn Strauss 2020-09-26 00:36:46 -04:00
parent 76bd8bba9a
commit 94c4c63773
3 changed files with 26 additions and 2 deletions

View File

@ -192,6 +192,7 @@ struct server {
buffer_plugin plugins;
time_t startup_ts;
time_t graceful_expire_ts;
uid_t uid;
gid_t gid;

View File

@ -1584,7 +1584,9 @@ void connection_periodic_maint (server * const srv, const time_t cur_ts) {
void connection_graceful_shutdown_maint (server *srv) {
connections * const conns = &srv->conns;
for (size_t ndx = 0; ndx < conns->used; ++ndx) {
const int graceful_expire =
(srv->graceful_expire_ts && srv->graceful_expire_ts < log_epoch_secs);
for (uint32_t ndx = 0; ndx < conns->used; ++ndx) {
connection * const con = conns->ptr[ndx];
int changed = 0;
@ -1611,6 +1613,11 @@ void connection_graceful_shutdown_maint (server *srv) {
changed = 1;
}
if (graceful_expire) {
connection_set_state_error(r, CON_STATE_ERROR);
changed = 1;
}
r->keep_alive = 0; /* disable keep-alive */
r->conf.bytes_per_second = 0; /* disable rate limit */

View File

@ -744,7 +744,23 @@ static int server_graceful_state_bg (server *srv) {
__attribute_cold__
static void server_graceful_state (server *srv) {
if (!srv_shutdown) connection_graceful_shutdown_maint(srv);
if (!srv_shutdown) {
if (0 == srv->graceful_expire_ts && srv->srvconf.feature_flags) {
data_unset * const du =
array_get_element_klen(srv->srvconf.feature_flags,
CONST_STR_LEN("server.graceful-shutdown-timeout"));
if (NULL != du) {
if (du->type == TYPE_STRING)
srv->graceful_expire_ts =
strtol(((data_string *)du)->value.ptr, NULL, 10);
else if (du->type == TYPE_INTEGER)
srv->graceful_expire_ts = ((data_integer *)du)->value;
if (srv->graceful_expire_ts)
srv->graceful_expire_ts += log_epoch_secs;
}
}
connection_graceful_shutdown_maint(srv);
}
if (!oneshot_fd
&& (2 == srv->sockets_disabled || 3 == srv->sockets_disabled)) return;