MEDIUM: servers: Use server_full to detect if a server is full

Instead of checking the value of served to know if the server is full,
make use of the newly introduced server_full where relevant, so that we
have less access to served.
This commit is contained in:
Olivier Houchard 2026-02-09 11:20:40 +01:00 committed by Olivier Houchard
parent cd66a94b63
commit 3121c00937
4 changed files with 25 additions and 4 deletions

View File

@ -78,7 +78,8 @@ static inline void pendconn_free(struct stream *s)
/* Returns 0 if all slots are full on a server, or 1 if there are slots available. */
static inline int server_has_room(const struct server *s) {
return !s->maxconn || s->served < srv_dynamic_maxconn(s);
return ((s->server_max_static && !s->server_full) ||
(!s->server_max_static && (!s->maxconn || s->served < srv_dynamic_maxconn(s))));
}
/* returns 0 if nothing has to be done for server <s> regarding queued connections,
@ -86,8 +87,8 @@ static inline int server_has_room(const struct server *s) {
* for and if/else usage.
*/
static inline int may_dequeue_tasks(const struct server *s, const struct proxy *p) {
return (s && (s->queues_not_empty || (p->queues_not_empty && srv_currently_usable(s))) &&
(!s->maxconn || s->served < srv_dynamic_maxconn(s)));
return (s && server_has_room(s) &&
(s->queues_not_empty || (p->queues_not_empty && srv_currently_usable(s))));
}
static inline int queue_limit_class(int class)

View File

@ -555,6 +555,7 @@ struct server {
__decl_thread(HA_SPINLOCK_T state_lock);/* protect the following state fields */
uint8_t queues_not_empty; /* Are the request queues not empty ? Only changed when the queues go from non-empty to empty, and vice-versa. Protected by the state_lock lock when changed */
uint8_t server_full; /* we reached maxconn, and can no longer process more requests, protected by the state_lock */
uint8_t server_max_static; /* the number of max requests for the server is static, and thus server_full can reliably be used */
};
/* data provided to EVENT_HDL_SUB_SERVER handlers through event_hdl facility */

View File

@ -597,7 +597,7 @@ struct server *get_server_rnd(struct stream *s, const struct server *avoid)
* the backend's queue instead.
*/
if (curr &&
(curr->queues_not_empty || (curr->maxconn && curr->served >= srv_dynamic_maxconn(curr))))
(curr->queues_not_empty || !server_has_room(curr)))
curr = NULL;
return curr;

View File

@ -3603,6 +3603,8 @@ int srv_postinit(struct server *srv)
goto out;
}
}
if (!srv->slowstart && srv->minconn == srv->maxconn)
srv->server_max_static = 1;
out:
return err_code;
@ -5948,12 +5950,19 @@ static struct task *server_warmup(struct task *t, void *context, unsigned int st
/* probably that we can refill this server with a bit more connections */
process_srv_queue(s, &full);
if (s->maxconn) {
HA_SPIN_LOCK(SERVER_LOCK, &s->state_lock);
s->server_full = (s->served >= s->maxconn);
HA_SPIN_UNLOCK(SERVER_LOCK, &s->state_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)));
else if (s->minconn == s->maxconn)
s->server_max_static = 1;
return t;
}
@ -6786,6 +6795,11 @@ static int _srv_update_status_op(struct server *s, enum srv_op_st_chg_cause caus
*/
xferred = process_srv_queue(s, &full);
if (s->maxconn) {
HA_SPIN_LOCK(SERVER_LOCK, &s->state_lock);
s->server_full = (s->served >= s->maxconn);
HA_SPIN_UNLOCK(SERVER_LOCK, &s->state_lock);
}
tmptrash = alloc_trash_chunk();
if (tmptrash) {
chunk_printf(tmptrash,
@ -6985,6 +6999,11 @@ static int _srv_update_status_adm(struct server *s, enum srv_adm_st_chg_cause ca
* We will take as many as we can handle.
*/
xferred = process_srv_queue(s, &full);
if (s->maxconn) {
HA_SPIN_LOCK(SERVER_LOCK, &s->state_lock);
s->server_full = (s->served >= s->maxconn);
HA_SPIN_UNLOCK(SERVER_LOCK, &s->state_lock);
}
}
else if (s->next_admin & SRV_ADMF_MAINT) {
/* remaining in maintenance mode, let's inform precisely about the