/* 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,
* 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)
__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 */
goto out;
}
}
+ if (!srv->slowstart && srv->minconn == srv->maxconn)
+ srv->server_max_static = 1;
out:
return err_code;
/* 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;
}
*/
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,
* 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