From: Amaury Denoyelle Date: Tue, 21 Sep 2021 09:51:29 +0000 (+0200) Subject: REORG: server: move slowstart init outside of checks X-Git-Tag: v2.5-dev8~160 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29d1ac133025dc586c79b599ebc21ccd3fbf1374;p=thirdparty%2Fhaproxy.git REORG: server: move slowstart init outside of checks 'slowstart' can be used without check on a server, with the CLI handlers 'enable/disable server'. Move the code to initialize and start the slowstart task outside of check.c. This change will also be reused to enable slowstart for dynamic servers. --- diff --git a/src/check.c b/src/check.c index 55f07939b1..aedbed1838 100644 --- a/src/check.c +++ b/src/check.c @@ -1418,38 +1418,6 @@ int start_check_task(struct check *check, int mininter, return 1; } -/* updates the server's weight during a warmup stage. Once the final weight is - * reached, the task automatically stops. Note that any server status change - * must have updated s->last_change accordingly. - */ -struct task *server_warmup(struct task *t, void *context, unsigned int state) -{ - struct server *s = context; - - /* by default, plan on stopping the task */ - t->expire = TICK_ETERNITY; - if ((s->next_admin & SRV_ADMF_MAINT) || - (s->next_state != SRV_ST_STARTING)) - return t; - - HA_SPIN_LOCK(SERVER_LOCK, &s->lock); - - /* recalculate the weights and update the state */ - server_recalc_eweight(s, 1); - - /* probably that we can refill this server with a bit more connections */ - pendconn_grab_from_px(s); - - HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock); - - /* get back there in 1 second or 1/20th of the slowstart interval, - * whichever is greater, resulting in small 5% steps. - */ - if (s->next_state == SRV_ST_STARTING) - t->expire = tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))); - return t; -} - /* * Start health-check. * Returns 0 if OK, ERR_FATAL on error, and prints the error in this case. @@ -1459,7 +1427,6 @@ static int start_checks() struct proxy *px; struct server *s; - struct task *t; int nbcheck=0, mininter=0, srvpos=0; /* 0- init the dummy frontend used to create all checks sessions */ @@ -1481,22 +1448,6 @@ static int start_checks() */ for (px = proxies_list; px; px = px->next) { for (s = px->srv; s; s = s->next) { - if (s->slowstart) { - if ((t = task_new(MAX_THREADS_MASK)) == NULL) { - ha_alert("Starting [%s:%s] check: out of memory.\n", px->id, s->id); - return ERR_ALERT | ERR_FATAL; - } - /* We need a warmup task that will be called when the server - * state switches from down to up. - */ - s->warmup = t; - t->process = server_warmup; - t->context = s; - /* server can be in this state only because of */ - if (s->next_state == SRV_ST_STARTING) - task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, (now.tv_sec - s->last_change)) / 20))); - } - if (s->check.state & CHK_ST_CONFIGURED) { nbcheck++; if ((srv_getinter(&s->check) >= SRV_CHK_INTER_THRES) && diff --git a/src/server.c b/src/server.c index 8558540d47..d770bdd3b0 100644 --- a/src/server.c +++ b/src/server.c @@ -4438,6 +4438,72 @@ static int srv_alloc_lb(struct server *sv, struct proxy *be) return 1; } +/* updates the server's weight during a warmup stage. Once the final weight is + * reached, the task automatically stops. Note that any server status change + * must have updated s->last_change accordingly. + */ +static struct task *server_warmup(struct task *t, void *context, unsigned int state) +{ + struct server *s = context; + + /* by default, plan on stopping the task */ + t->expire = TICK_ETERNITY; + if ((s->next_admin & SRV_ADMF_MAINT) || + (s->next_state != SRV_ST_STARTING)) + return t; + + HA_SPIN_LOCK(SERVER_LOCK, &s->lock); + + /* recalculate the weights and update the state */ + server_recalc_eweight(s, 1); + + /* probably that we can refill this server with a bit more connections */ + pendconn_grab_from_px(s); + + HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock); + + /* get back there in 1 second or 1/20th of the slowstart interval, + * whichever is greater, resulting in small 5% steps. + */ + if (s->next_state == SRV_ST_STARTING) + t->expire = tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))); + return t; +} + +/* Allocate the slowstart task if the server is configured with a slowstart + * timer. If server next_state is SRV_ST_STARTING, the task is scheduled. + * + * Returns 0 on success else non-zero. + */ +static int init_srv_slowstart(struct server *srv) +{ + struct task *t; + + if (srv->slowstart) { + if ((t = task_new(MAX_THREADS_MASK)) == NULL) { + ha_alert("Cannot activate slowstart for server %s/%s: out of memory.\n", srv->proxy->id, srv->id); + return ERR_ALERT | ERR_FATAL; + } + + /* We need a warmup task that will be called when the server + * state switches from down to up. + */ + srv->warmup = t; + t->process = server_warmup; + t->context = srv; + + /* server can be in this state only because of */ + if (srv->next_state == SRV_ST_STARTING) { + task_schedule(srv->warmup, + tick_add(now_ms, + MS_TO_TICKS(MAX(1000, (now.tv_sec - srv->last_change)) / 20))); + } + } + + return ERR_NONE; +} +REGISTER_POST_SERVER_CHECK(init_srv_slowstart); + /* Memory allocation and initialization of the per_thr field. * Returns 0 if the field has been successfully initialized, -1 on failure. */