src/backend.c
int srv_redispatch_connect(struct session *t)
{
	struct server *srv;
	int conn_err;

	/* We know that we don't have any connection pending, so we will
	 * try to get a new one, and wait in this state if it's queued
	 */
 redispatch:
	conn_err = assign_server_and_queue(t);
	srv = objt_server(t->target);

	switch (conn_err) {
	case SRV_STATUS_OK:
		break;

	case SRV_STATUS_FULL:
		/* The server has reached its maxqueue limit. Either PR_O_REDISP is set
		 * and we can redispatch to another server, or it is not and we return
		 * 503. This only makes sense in DIRECT mode however, because normal LB
		 * algorithms would never select such a server, and hash algorithms
		 * would bring us on the same server again. Note that t->target is set
		 * in this case.
		 */
		if (((t->flags & (SN_DIRECT|SN_FORCE_PRST)) == SN_DIRECT) &&
		    (t->be->options & PR_O_REDISP)) {
			t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
			goto redispatch;
		}

		if (!t->req->cons->err_type) {
			t->req->cons->err_type = SI_ET_QUEUE_ERR;
			t->req->cons->err_loc = srv;
		}

		srv->counters.failed_conns++;
		t->be->be_counters.failed_conns++;
		return 1;

	case SRV_STATUS_NOSRV:
		/* note: it is guaranteed that srv == NULL here */
		if (!t->req->cons->err_type) {
			t->req->cons->err_type = SI_ET_CONN_ERR;
			t->req->cons->err_loc = NULL;
		}

		t->be->be_counters.failed_conns++;
		return 1;

	case SRV_STATUS_QUEUED:
		t->req->cons->exp = tick_add_ifset(now_ms, t->be->timeout.queue);
		t->req->cons->state = SI_ST_QUE;
		/* do nothing else and do not wake any other session up */
		return 1;

	case SRV_STATUS_INTERNAL:
	default:
		if (!t->req->cons->err_type) {
			t->req->cons->err_type = SI_ET_CONN_OTHER;
			t->req->cons->err_loc = srv;
		}

		if (srv)
			srv_inc_sess_ctr(srv);
		if (srv)
			srv->counters.failed_conns++;
		t->be->be_counters.failed_conns++;

		/* release other sessions waiting for this server */
		if (may_dequeue_tasks(srv, t->be))
			process_srv_queue(srv);
		return 1;
	}
	/* if we get here, it's because we got SRV_STATUS_OK, which also
	 * means that the connection has not been queued.
	 */
	return 0;
}
/* This function performs the "redispatch" part of a connection attempt. It
 * will assign a server if required, queue the connection if required, and
 * handle errors that might arise at this level. It can change the server
 * state. It will return 1 if it encounters an error, switches the server
 * state, or has to queue a connection. Otherwise, it will return 0 indicating
 * that the connection is ready to use.
 */
This function performs the "redispatch" part of a connection attempt. It
will assign a server if required, queue the connection if required, and
handle errors that might arise at this level. It can change the server
state. It will return 1 if it encounters an error, switches the server
state, or has to queue a connection. Otherwise, it will return 0 indicating
that the connection is ready to use.
This function performs the " redispatch " part of a connection attempt . It will assign a server if required queue the connection if required and handle errors that might arise at this level . It can change the server state . It will return 1 if it encounters an error switches the server state or has to queue a connection . Otherwise it will return 0 indicating that the connection is ready to use .
int srv_redispatch_connect(struct session *t)
{
	struct server *srv;
	int conn_err;
 redispatch:
	conn_err = assign_server_and_queue(t);
	srv = objt_server(t->target);
	switch (conn_err) {
	case SRV_STATUS_OK:
		break;
	case SRV_STATUS_FULL:
		if (((t->flags & (SN_DIRECT|SN_FORCE_PRST)) == SN_DIRECT) &&
		    (t->be->options & PR_O_REDISP)) {
			t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
			goto redispatch;
		}
		if (!t->req->cons->err_type) {
			t->req->cons->err_type = SI_ET_QUEUE_ERR;
			t->req->cons->err_loc = srv;
		}
		srv->counters.failed_conns++;
		t->be->be_counters.failed_conns++;
		return 1;
	case SRV_STATUS_NOSRV:
		if (!t->req->cons->err_type) {
			t->req->cons->err_type = SI_ET_CONN_ERR;
			t->req->cons->err_loc = NULL;
		}
		t->be->be_counters.failed_conns++;
		return 1;
	case SRV_STATUS_QUEUED:
		t->req->cons->exp = tick_add_ifset(now_ms, t->be->timeout.queue);
		t->req->cons->state = SI_ST_QUE;
		return 1;
	case SRV_STATUS_INTERNAL:
	default:
		if (!t->req->cons->err_type) {
			t->req->cons->err_type = SI_ET_CONN_OTHER;
			t->req->cons->err_loc = srv;
		}
		if (srv)
			srv_inc_sess_ctr(srv);
		if (srv)
			srv->counters.failed_conns++;
		t->be->be_counters.failed_conns++;
		if (may_dequeue_tasks(srv, t->be))
			process_srv_queue(srv);
		return 1;
	}
	return 0;
}
int srv_redispatch_connect ( struct session * t ) { struct server * srv ; int conn_err ; redispatch : conn_err = assign_server_and_queue ( t ) ; srv = objt_server ( t -> target ) ; switch ( conn_err ) { case SRV_STATUS_OK : break ; case SRV_STATUS_FULL : if ( ( ( t -> flags & ( SN_DIRECT | SN_FORCE_PRST ) ) == SN_DIRECT ) && ( t -> be -> options & PR_O_REDISP ) ) { t -> flags &= ~ ( SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET ) ; goto redispatch ; } if ( ! t -> req -> cons -> err_type ) { t -> req -> cons -> err_type = SI_ET_QUEUE_ERR ; t -> req -> cons -> err_loc = srv ; } srv -> counters . failed_conns ++ ; t -> be -> be_counters . failed_conns ++ ; return 1 ; case SRV_STATUS_NOSRV : if ( ! t -> req -> cons -> err_type ) { t -> req -> cons -> err_type = SI_ET_CONN_ERR ; t -> req -> cons -> err_loc = NULL ; } t -> be -> be_counters . failed_conns ++ ; return 1 ; case SRV_STATUS_QUEUED : t -> req -> cons -> exp = tick_add_ifset ( now_ms , t -> be -> timeout . queue ) ; t -> req -> cons -> state = SI_ST_QUE ; return 1 ; case SRV_STATUS_INTERNAL : default : if ( ! t -> req -> cons -> err_type ) { t -> req -> cons -> err_type = SI_ET_CONN_OTHER ; t -> req -> cons -> err_loc = srv ; } if ( srv ) srv_inc_sess_ctr ( srv ) ; if ( srv ) srv -> counters . failed_conns ++ ; t -> be -> be_counters . failed_conns ++ ; if ( may_dequeue_tasks ( srv , t -> be ) ) process_srv_queue ( srv ) ; return 1 ; } return 0 ; }
This function performs the "redispatch" part of a connection attempt.
This function performs the " redispatch " part of a connection attempt .
/* We know that we don't have any connection pending, so we will
	 * try to get a new one, and wait in this state if it's queued
	 */ /* The server has reached its maxqueue limit. Either PR_O_REDISP is set
		 * and we can redispatch to another server, or it is not and we return
		 * 503. This only makes sense in DIRECT mode however, because normal LB
		 * algorithms would never select such a server, and hash algorithms
		 * would bring us on the same server again. Note that t->target is set
		 * in this case.
		 */ /* note: it is guaranteed that srv == NULL here */ /* do nothing else and do not wake any other session up */ /* release other sessions waiting for this server */ /* if we get here, it's because we got SRV_STATUS_OK, which also
	 * means that the connection has not been queued.
	 */