/* Dumps all registered "server" keywords to the <out> string pointer. */
void srv_dump_kws(char **out);
+/* Recomputes the server's eweight based on its state, uweight, the current time,
+ * and the proxy's algorihtm. To be used after updating sv->uweight. The warmup
+ * state is automatically disabled if the time is elapsed.
+ */
+void server_recalc_eweight(struct server *sv);
+
/*
* Parses weight_str and configures sv accordingly.
* Returns NULL on success, error message string otherwise.
if (s->slowstart > 0) {
s->state |= SRV_WARMINGUP;
- if (s->proxy->lbprm.algo & BE_LB_PROP_DYN) {
- /* For dynamic algorithms, start at the first step of the weight,
- * without multiplying by BE_WEIGHT_SCALE.
- */
- s->eweight = s->uweight;
- if (s->proxy->lbprm.update_server_eweight)
- s->proxy->lbprm.update_server_eweight(s);
- }
task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
}
- if (s->proxy->lbprm.set_server_status_up)
- s->proxy->lbprm.set_server_status_up(s);
+
+ server_recalc_eweight(s);
/* If the server is set with "on-marked-up shutdown-backup-sessions",
* and it's not a backup server and its effective weight is > 0,
if ((s->state & (SRV_RUNNING|SRV_WARMINGUP|SRV_MAINTAIN)) != (SRV_RUNNING|SRV_WARMINGUP))
return t;
- if (now.tv_sec < s->last_change || now.tv_sec >= s->last_change + s->slowstart) {
- /* go to full throttle if the slowstart interval is reached */
- s->state &= ~SRV_WARMINGUP;
- if (s->proxy->lbprm.algo & BE_LB_PROP_DYN)
- s->eweight = s->uweight * BE_WEIGHT_SCALE;
- if (s->proxy->lbprm.update_server_eweight)
- s->proxy->lbprm.update_server_eweight(s);
- }
- else if (s->proxy->lbprm.algo & BE_LB_PROP_DYN) {
- /* for dynamic algorithms, let's slowly update the weight */
- s->eweight = (BE_WEIGHT_SCALE * (now.tv_sec - s->last_change) +
- s->slowstart - 1) / s->slowstart;
- s->eweight *= s->uweight;
- if (s->proxy->lbprm.update_server_eweight)
- s->proxy->lbprm.update_server_eweight(s);
- }
- /* Note that static algorithms are already running at full throttle */
+ server_recalc_eweight(s);
/* probably that we can refill this server with a bit more connections */
check_for_pending(s);
p->lbprm.wdiv = BE_WEIGHT_SCALE;
for (srv = p->srv; srv; srv = srv->next) {
- srv->prev_eweight = srv->eweight = srv->uweight * BE_WEIGHT_SCALE;
+ srv->eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
+ srv->prev_eweight = srv->eweight;
srv->prev_state = srv->state;
}
p->lbprm.wdiv = BE_WEIGHT_SCALE;
for (srv = p->srv; srv; srv = srv->next) {
- srv->prev_eweight = srv->eweight = srv->uweight * BE_WEIGHT_SCALE;
+ srv->eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
+ srv->prev_eweight = srv->eweight;
srv->prev_state = srv->state;
}
p->lbprm.wdiv = BE_WEIGHT_SCALE;
for (srv = p->srv; srv; srv = srv->next) {
- srv->prev_eweight = srv->eweight = srv->uweight * BE_WEIGHT_SCALE;
+ srv->eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
+ srv->prev_eweight = srv->eweight;
srv->prev_state = srv->state;
}
p->lbprm.wdiv = BE_WEIGHT_SCALE;
for (srv = p->srv; srv; srv = srv->next) {
- srv->prev_eweight = srv->eweight = srv->uweight * BE_WEIGHT_SCALE;
+ srv->eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
+ srv->prev_eweight = srv->eweight;
srv->prev_state = srv->state;
}
act = bck = 0;
for (srv = p->srv; srv; srv = srv->next) {
- srv->eweight = srv->uweight / pgcd;
+ srv->eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
srv->prev_eweight = srv->eweight;
srv->prev_state = srv->state;
if (srv->state & SRV_BACKUP)
else
sv->uweight = 0;
- if (px->lbprm.algo & BE_LB_PROP_DYN) {
- /* we must take care of not pushing the server to full throttle during slow starts */
- if ((sv->state & SRV_WARMINGUP) && (px->lbprm.algo & BE_LB_PROP_DYN))
- sv->eweight = (BE_WEIGHT_SCALE * (now.tv_sec - sv->last_change) + sv->slowstart - 1) / sv->slowstart;
- else
- sv->eweight = BE_WEIGHT_SCALE;
- sv->eweight *= sv->uweight;
- } else {
- sv->eweight = sv->uweight;
- }
+ server_recalc_eweight(sv);
- /* static LB algorithms are a bit harder to update */
- if (px->lbprm.update_server_eweight)
- px->lbprm.update_server_eweight(sv);
- else if (sv->eweight) {
- if (px->lbprm.set_server_status_up)
- px->lbprm.set_server_status_up(sv);
- }
- else {
- if (px->lbprm.set_server_status_down)
- px->lbprm.set_server_status_down(sv);
- }
altered_servers++;
total_servers++;
break;
srv_register_keywords(&srv_kws);
}
+/* Recomputes the server's eweight based on its state, uweight, the current time,
+ * and the proxy's algorihtm. To be used after updating sv->uweight. The warmup
+ * state is automatically disabled if the time is elapsed.
+ */
+void server_recalc_eweight(struct server *sv)
+{
+ struct proxy *px = sv->proxy;
+ unsigned w;
+
+ if (now.tv_sec < sv->last_change || now.tv_sec >= sv->last_change + sv->slowstart) {
+ /* go to full throttle if the slowstart interval is reached */
+ sv->state &= ~SRV_WARMINGUP;
+ }
+
+ /* We must take care of not pushing the server to full throttle during slow starts.
+ * It must also start immediately, at least at the minimal step when leaving maintenance.
+ */
+ if ((sv->state & SRV_WARMINGUP) && (px->lbprm.algo & BE_LB_PROP_DYN))
+ w = (px->lbprm.wdiv * (now.tv_sec - sv->last_change) + sv->slowstart) / sv->slowstart;
+ else
+ w = px->lbprm.wdiv;
+
+ sv->eweight = (sv->uweight * w + px->lbprm.wmult - 1) / px->lbprm.wmult;
+
+ /* now propagate the status change to any LB algorithms */
+ if (px->lbprm.update_server_eweight)
+ px->lbprm.update_server_eweight(sv);
+ else if (sv->eweight) {
+ if (px->lbprm.set_server_status_up)
+ px->lbprm.set_server_status_up(sv);
+ }
+ else {
+ if (px->lbprm.set_server_status_down)
+ px->lbprm.set_server_status_down(sv);
+ }
+}
+
/*
* Parses weight_str and configures sv accordingly.
* Returns NULL on success, error message string otherwise.
return "Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.\n";
sv->uweight = w;
-
- if (px->lbprm.algo & BE_LB_PROP_DYN) {
- /* we must take care of not pushing the server to full throttle during slow starts */
- if ((sv->state & SRV_WARMINGUP))
- sv->eweight = (BE_WEIGHT_SCALE * (now.tv_sec - sv->last_change) + sv->slowstart - 1) / sv->slowstart;
- else
- sv->eweight = BE_WEIGHT_SCALE;
- sv->eweight *= sv->uweight;
- } else {
- sv->eweight = sv->uweight;
- }
-
- /* static LB algorithms are a bit harder to update */
- if (px->lbprm.update_server_eweight)
- px->lbprm.update_server_eweight(sv);
- else if (sv->eweight) {
- if (px->lbprm.set_server_status_up)
- px->lbprm.set_server_status_up(sv);
- }
- else {
- if (px->lbprm.set_server_status_down)
- px->lbprm.set_server_status_down(sv);
- }
+ server_recalc_eweight(sv);
return NULL;
}