src/backend.c
int assign_server_and_queue(struct session *s)
{
	struct pendconn *p;
	struct server *srv;
	int err;

	if (s->pend_pos)
		return SRV_STATUS_INTERNAL;

	err = SRV_STATUS_OK;
	if (!(s->flags & SN_ASSIGNED)) {
		struct server *prev_srv = objt_server(s->target);

		err = assign_server(s);
		if (prev_srv) {
			/* This session was previously assigned to a server. We have to
			 * update the session's and the server's stats :
			 *  - if the server changed :
			 *    - set TX_CK_DOWN if txn.flags was TX_CK_VALID
			 *    - set SN_REDISP if it was successfully redispatched
			 *    - increment srv->redispatches and be->redispatches
			 *  - if the server remained the same : update retries.
			 */

			if (prev_srv != objt_server(s->target)) {
				if ((s->txn.flags & TX_CK_MASK) == TX_CK_VALID) {
					s->txn.flags &= ~TX_CK_MASK;
					s->txn.flags |= TX_CK_DOWN;
				}
				s->flags |= SN_REDISP;
				prev_srv->counters.redispatches++;
				s->be->be_counters.redispatches++;
			} else {
				prev_srv->counters.retries++;
				s->be->be_counters.retries++;
			}
		}
	}

	switch (err) {
	case SRV_STATUS_OK:
		/* we have SN_ASSIGNED set */
		srv = objt_server(s->target);
		if (!srv)
			return SRV_STATUS_OK;   /* dispatch or proxy mode */

		/* If we already have a connection slot, no need to check any queue */
		if (s->srv_conn == srv)
			return SRV_STATUS_OK;

		/* OK, this session already has an assigned server, but no
		 * connection slot yet. Either it is a redispatch, or it was
		 * assigned from persistence information (direct mode).
		 */
		if ((s->flags & SN_REDIRECTABLE) && srv->rdr_len) {
			/* server scheduled for redirection, and already assigned. We
			 * don't want to go further nor check the queue.
			 */
			sess_change_server(s, srv); /* not really needed in fact */
			return SRV_STATUS_OK;
		}

		/* We might have to queue this session if the assigned server is full.
		 * We know we have to queue it into the server's queue, so if a maxqueue
		 * is set on the server, we must also check that the server's queue is
		 * not full, in which case we have to return FULL.
		 */
		if (srv->maxconn &&
		    (srv->nbpend || srv->served >= srv_dynamic_maxconn(srv))) {

			if (srv->maxqueue > 0 && srv->nbpend >= srv->maxqueue)
				return SRV_STATUS_FULL;

			p = pendconn_add(s);
			if (p)
				return SRV_STATUS_QUEUED;
			else
				return SRV_STATUS_INTERNAL;
		}

		/* OK, we can use this server. Let's reserve our place */
		sess_change_server(s, srv);
		return SRV_STATUS_OK;

	case SRV_STATUS_FULL:
		/* queue this session into the proxy's queue */
		p = pendconn_add(s);
		if (p)
			return SRV_STATUS_QUEUED;
		else
			return SRV_STATUS_INTERNAL;

	case SRV_STATUS_NOSRV:
		return err;

	case SRV_STATUS_INTERNAL:
		return err;

	default:
		return SRV_STATUS_INTERNAL;
	}
}
/* This function assigns a server to session <s> if required, and can add the
 * connection to either the assigned server's queue or to the proxy's queue.
 * If ->srv_conn is set, the session is first released from the server.
 * It may also be called with SN_DIRECT and/or SN_ASSIGNED though. It will
 * be called before any connection and after any retry or redispatch occurs.
 *
 * It is not allowed to call this function with a session in a queue.
 *
 * Returns :
 *
 *   SRV_STATUS_OK       if everything is OK.
 *   SRV_STATUS_NOSRV    if no server is available. objt_server(s->target) = NULL.
 *   SRV_STATUS_QUEUED   if the connection has been queued.
 *   SRV_STATUS_FULL     if the server(s) is/are saturated and the
 *                       connection could not be queued at the server's,
 *                       which may be NULL if we queue on the backend.
 *   SRV_STATUS_INTERNAL for other unrecoverable errors.
 *
 */
This function assigns a server to session  if required, and can add the
connection to either the assigned server's queue or to the proxy's queue.
If ->srv_conn is set, the session is first released from the server.
It may also be called with SN_DIRECT and/or SN_ASSIGNED though. It will
be called before any connection and after any retry or redispatch occurs.

It is not allowed to call this function with a session in a queue.

Returns .

SRV_STATUS_OK       if everything is OK.
SRV_STATUS_NOSRV    if no server is available.
This function assigns a server to session if required and can add the connection to either the assigned server ' s queue or to the proxy ' s queue . If - > srv_conn is set the session is first released from the server . It may also be called with SN_DIRECT and / or SN_ASSIGNED though . It will be called before any connection and after any retry or redispatch occurs . It is not allowed to call this function with a session in a queue . Returns . SRV_STATUS_OK if everything is OK . SRV_STATUS_NOSRV if no server is available .
int assign_server_and_queue(struct session *s)
{
	struct pendconn *p;
	struct server *srv;
	int err;
	if (s->pend_pos)
		return SRV_STATUS_INTERNAL;
	err = SRV_STATUS_OK;
	if (!(s->flags & SN_ASSIGNED)) {
		struct server *prev_srv = objt_server(s->target);
		err = assign_server(s);
		if (prev_srv) {
			if (prev_srv != objt_server(s->target)) {
				if ((s->txn.flags & TX_CK_MASK) == TX_CK_VALID) {
					s->txn.flags &= ~TX_CK_MASK;
					s->txn.flags |= TX_CK_DOWN;
				}
				s->flags |= SN_REDISP;
				prev_srv->counters.redispatches++;
				s->be->be_counters.redispatches++;
			} else {
				prev_srv->counters.retries++;
				s->be->be_counters.retries++;
			}
		}
	}
	switch (err) {
	case SRV_STATUS_OK:
		srv = objt_server(s->target);
		if (!srv)
			return SRV_STATUS_OK;   
		if (s->srv_conn == srv)
			return SRV_STATUS_OK;
		if ((s->flags & SN_REDIRECTABLE) && srv->rdr_len) {
			sess_change_server(s, srv); 
			return SRV_STATUS_OK;
		}
		if (srv->maxconn &&
		    (srv->nbpend || srv->served >= srv_dynamic_maxconn(srv))) {
			if (srv->maxqueue > 0 && srv->nbpend >= srv->maxqueue)
				return SRV_STATUS_FULL;
			p = pendconn_add(s);
			if (p)
				return SRV_STATUS_QUEUED;
			else
				return SRV_STATUS_INTERNAL;
		}
		sess_change_server(s, srv);
		return SRV_STATUS_OK;
	case SRV_STATUS_FULL:
		p = pendconn_add(s);
		if (p)
			return SRV_STATUS_QUEUED;
		else
			return SRV_STATUS_INTERNAL;
	case SRV_STATUS_NOSRV:
		return err;
	case SRV_STATUS_INTERNAL:
		return err;
	default:
		return SRV_STATUS_INTERNAL;
	}
}
int assign_server_and_queue ( struct session * s ) { struct pendconn * p ; struct server * srv ; int err ; if ( s -> pend_pos ) return SRV_STATUS_INTERNAL ; err = SRV_STATUS_OK ; if ( ! ( s -> flags & SN_ASSIGNED ) ) { struct server * prev_srv = objt_server ( s -> target ) ; err = assign_server ( s ) ; if ( prev_srv ) { if ( prev_srv != objt_server ( s -> target ) ) { if ( ( s -> txn . flags & TX_CK_MASK ) == TX_CK_VALID ) { s -> txn . flags &= ~ TX_CK_MASK ; s -> txn . flags |= TX_CK_DOWN ; } s -> flags |= SN_REDISP ; prev_srv -> counters . redispatches ++ ; s -> be -> be_counters . redispatches ++ ; } else { prev_srv -> counters . retries ++ ; s -> be -> be_counters . retries ++ ; } } } switch ( err ) { case SRV_STATUS_OK : srv = objt_server ( s -> target ) ; if ( ! srv ) return SRV_STATUS_OK ; if ( s -> srv_conn == srv ) return SRV_STATUS_OK ; if ( ( s -> flags & SN_REDIRECTABLE ) && srv -> rdr_len ) { sess_change_server ( s , srv ) ; return SRV_STATUS_OK ; } if ( srv -> maxconn && ( srv -> nbpend || srv -> served >= srv_dynamic_maxconn ( srv ) ) ) { if ( srv -> maxqueue > 0 && srv -> nbpend >= srv -> maxqueue ) return SRV_STATUS_FULL ; p = pendconn_add ( s ) ; if ( p ) return SRV_STATUS_QUEUED ; else return SRV_STATUS_INTERNAL ; } sess_change_server ( s , srv ) ; return SRV_STATUS_OK ; case SRV_STATUS_FULL : p = pendconn_add ( s ) ; if ( p ) return SRV_STATUS_QUEUED ; else return SRV_STATUS_INTERNAL ; case SRV_STATUS_NOSRV : return err ; case SRV_STATUS_INTERNAL : return err ; default : return SRV_STATUS_INTERNAL ; } }
This function assigns a server to session <s> if required, and can add the
 connection to either the assigned server's queue or to the proxy's queue.
This function assigns a server to session <s > if required and can add the connection to either the assigned server ' s queue or to the proxy ' s queue .
/* This session was previously assigned to a server. We have to
			 * update the session's and the server's stats :
			 *  - if the server changed :
			 *    - set TX_CK_DOWN if txn.flags was TX_CK_VALID
			 *    - set SN_REDISP if it was successfully redispatched
			 *    - increment srv->redispatches and be->redispatches
			 *  - if the server remained the same : update retries.
			 */ /* we have SN_ASSIGNED set */ /* dispatch or proxy mode */ /* If we already have a connection slot, no need to check any queue */ /* OK, this session already has an assigned server, but no
		 * connection slot yet. Either it is a redispatch, or it was
		 * assigned from persistence information (direct mode).
		 */ /* server scheduled for redirection, and already assigned. We
			 * don't want to go further nor check the queue.
			 */ /* not really needed in fact */ /* We might have to queue this session if the assigned server is full.
		 * We know we have to queue it into the server's queue, so if a maxqueue
		 * is set on the server, we must also check that the server's queue is
		 * not full, in which case we have to return FULL.
		 */ /* OK, we can use this server. Let's reserve our place */ /* queue this session into the proxy's queue */