From 4c8c2b5f084443debec42406fdad93894f315fbd Mon Sep 17 00:00:00 2001 From: willy tarreau Date: Fri, 24 Mar 2006 19:36:41 +0100 Subject: [PATCH] * re-architectured the server round-robin mechanism to ease integration of other algorithms. It now relies on the number of active and backup servers. --- haproxy.c | 93 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/haproxy.c b/haproxy.c index 68af4e59d2..0a935c0a10 100644 --- a/haproxy.c +++ b/haproxy.c @@ -1785,57 +1785,81 @@ static inline void session_free(struct session *s) { /* - * This function tries to find a running server for the proxy . A first - * pass looks for active servers, and if none is found, a second pass also - * looks for backup servers. - * If no valid server is found, NULL is returned and px->cursrv is left undefined. + * This function recounts the number of usable active and backup servers for + * proxy

. These numbers are returned into the p->srv_act and p->srv_bck. */ -static inline struct server *find_server(struct proxy *px) { - struct server *srv = px->cursrv; +static inline void recount_servers(struct proxy *px) { + struct server *srv; + + px->srv_act = 0; px->srv_bck = 0; + for (srv = px->srv; srv != NULL; srv = srv->next) { + if (srv->state & SRV_RUNNING) { + if (srv->state & SRV_BACKUP) + px->srv_bck++; + else + px->srv_act++; + } + } +} + +/* + * This function tries to find a running server for the proxy following + * the round-robin method. Depending on the number of active/backup servers, + * it will either look for active servers, or for backup servers. + * If any server is found, it will be returned and px->cursrv will be updated + * to point to the next server. If no valid server is found, NULL is returned. + */ +static inline struct server *get_server_rr(struct proxy *px) { + struct server *srv; struct server *end; - int ignore_backup = 1; - do { + if (px->srv_act) { + srv = px->cursrv; if (srv == NULL) srv = px->srv; end = srv; do { - if (srv->state & SRV_RUNNING - && !((srv->state & SRV_BACKUP) && ignore_backup)) + if ((srv->state & (SRV_RUNNING | SRV_BACKUP)) == SRV_RUNNING) { + px->cursrv = srv->next; return srv; + } + srv = srv->next; if (srv == NULL) srv = px->srv; } while (srv != end); + /* note that theorically we should not get there */ + } + if (px->srv_bck) { /* By default, we look for the first backup server if all others are * DOWN. But in some cases, it may be desirable to load-balance across * all backup servers. */ - if (!(px->options & PR_O_USE_ALL_BK)) + if (px->options & PR_O_USE_ALL_BK) + srv = px->cursrv; + else + srv = px->srv; + + if (srv == NULL) srv = px->srv; + end = srv; + do { + if (srv->state & SRV_RUNNING) { + px->cursrv = srv->next; + return srv; + } + srv = srv->next; + if (srv == NULL) + srv = px->srv; + } while (srv != end); + /* note that theorically we should not get there */ + } - } while (ignore_backup--); + /* if we get there, it means there are no available servers at all */ return NULL; } -/* - * This function recounts the number of usable active and backup servers for - * proxy

. These numbers are returned into the p->srv_act and p->srv_bck. - */ -static inline void recount_servers(struct proxy *px) { - struct server *srv; - - px->srv_act = 0; px->srv_bck = 0; - for (srv = px->srv; srv != NULL; srv = srv->next) { - if (srv->state & SRV_RUNNING) { - if (srv->state & SRV_BACKUP) - px->srv_bck++; - else - px->srv_act++; - } - } -} /* * This function initiates a connection to the current server (s->srv) if (s->direct) @@ -1860,17 +1884,16 @@ int connect_server(struct session *s) { s->srv_addr = s->srv->addr; } else if (s->proxy->options & PR_O_BALANCE) { + if (!s->proxy->srv_act && !s->proxy->srv_bck) + return SN_ERR_SRVTO; + if (s->proxy->options & PR_O_BALANCE_RR) { struct server *srv; - srv = find_server(s->proxy); - - if (srv == NULL) /* no server left */ - return SN_ERR_SRVTO; - + srv = get_server_rr(s->proxy); + /* srv cannot be NULL */ s->srv_addr = srv->addr; s->srv = srv; - s->proxy->cursrv = srv->next; } else /* unknown balancing algorithm */ return SN_ERR_INTERNAL; -- 2.47.3