}
/* returns 0 if nothing has to be done for server <s> regarding queued connections,
- * and non-zero otherwise. If the server is down, we always return zero. Suited for
- * and if/else usage.
+ * and non-zero otherwise. If the server is down, we only check its own queue. Suited
+ * for and if/else usage.
*/
static inline int may_dequeue_tasks(const struct server *s, const struct proxy *p) {
- return (s && (s->state & SRV_RUNNING) && (s->nbpend || p->nbpend) &&
+ return (s && (s->nbpend || (p->nbpend && (s->state & SRV_RUNNING))) &&
(!s->maxconn || s->cur_sess < srv_dynamic_maxconn(s)));
}
* returned. Note that neither <srv> nor <px> may be NULL.
* Priority is given to the oldest request in the queue if both <srv> and <px>
* have pending requests. This ensures that no request will be left unserved.
+ * The <px> queue is not considered if the server is not RUNNING. The <srv>
+ * queue is still considered in this case, because if some connections remain
+ * there, it means that some requests have been forced there after it was seen
+ * down (eg: due to option persist).
* The session is immediately marked as "assigned", and both its <srv> and
* <srv_conn> are set to <srv>,
*/
ps = pendconn_from_srv(srv);
pp = pendconn_from_px(px);
/* we want to get the definitive pendconn in <ps> */
- if (!pp) {
+ if (!pp || !(srv->state & SRV_RUNNING)) {
if (!ps)
return NULL;
} else {
if (s->pend_pos)
pendconn_free(s->pend_pos);
- if (s->srv) /* there may be requests left pending in queue */
+ if (s->srv && may_dequeue_tasks(s->srv, s->be)) /* there may be requests left pending in queue */
process_srv_queue(s->srv);
+
if (unlikely(s->srv_conn)) {
/* the session still has a reserved slot on a server, but
* it should normally be only the same as the one above,