diff --git a/degesch.c b/degesch.c index a570733..8abb53a 100644 --- a/degesch.c +++ b/degesch.c @@ -1116,6 +1116,7 @@ struct server enum server_state state; ///< Connection state struct connector *connector; ///< Connection establisher + unsigned reconnect_attempt; ///< Number of reconnect attempt bool manual_disconnect; ///< Don't reconnect after disconnect int socket; ///< Socket FD of the server @@ -1613,6 +1614,17 @@ static struct config_schema g_config_behaviour[] = .type = CONFIG_ITEM_BOOLEAN, .default_ = "off", .on_change = on_config_debug_mode_change }, + + { .name = "reconnect_delay_growing", + .comment = "Growing factor for reconnect delay", + .type = CONFIG_ITEM_INTEGER, + .validate = config_validate_nonnegative, + .default_ = "2" }, + { .name = "reconnect_delay_max", + .comment = "Maximum reconnect delay in seconds", + .type = CONFIG_ITEM_INTEGER, + .validate = config_validate_nonnegative, + .default_ = "600" }, {} }; @@ -3467,7 +3479,18 @@ irc_queue_reconnect (struct server *s) return; int64_t delay = get_config_integer (s->config, "reconnect_delay"); - // TODO: exponentional backoff + int64_t delay_factor = get_config_integer (s->ctx->config.root, + "behaviour.reconnect_delay_growing"); + int64_t delay_max = get_config_integer (s->ctx->config.root, + "behaviour.reconnect_delay_max"); + + for (unsigned i = 0; i < s->reconnect_attempt; i++) + delay *= delay_factor; + if (delay > delay_max || delay < 0) + delay = delay_max; + + s->reconnect_attempt++; + // XXX: maybe add a state for when a connect is queued? hard_assert (s->state == IRC_DISCONNECTED); log_server_status (s, s->buffer, @@ -3671,7 +3694,10 @@ irc_disconnect (struct server *s) else if (s->manual_disconnect) s->manual_disconnect = false; else + { + s->reconnect_attempt = 0; irc_queue_reconnect (s); + } refresh_prompt (s->ctx); } @@ -4420,6 +4446,8 @@ irc_initiate_connect (struct server *s) return; } + s->reconnect_attempt = 0; + struct str_vector servers; str_vector_init (&servers); cstr_split_ignore_empty (addresses, ',', &servers);