@@ -169,15 +169,63 @@ static char *get_cookie_param(request_rec *r, const char *name)
169169/* Find the worker that has the 'route' defined
170170 */
171171static proxy_worker * find_route_worker (proxy_balancer * balancer ,
172- const char * route )
172+ const char * route , request_rec * r )
173173{
174174 int i ;
175- proxy_worker * worker = (proxy_worker * )balancer -> workers -> elts ;
176- for (i = 0 ; i < balancer -> workers -> nelts ; i ++ ) {
177- if (* (worker -> s -> route ) && strcmp (worker -> s -> route , route ) == 0 ) {
178- return worker ;
175+ int checking_standby = 0 ;
176+ int checked_standby = 0 ;
177+
178+ proxy_worker * worker ;
179+ while (!checked_standby ) {
180+ worker = (proxy_worker * )balancer -> workers -> elts ;
181+ for (i = 0 ; i < balancer -> workers -> nelts ; i ++ , worker ++ ) {
182+ if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY (worker ) : PROXY_WORKER_IS_STANDBY (worker )) )
183+ continue ;
184+ if (* (worker -> s -> route ) && strcmp (worker -> s -> route , route ) == 0 ) {
185+ if (worker && PROXY_WORKER_IS_USABLE (worker )) {
186+ return worker ;
187+ } else {
188+ /*
189+ * If the worker is in error state run
190+ * retry on that worker. It will be marked as
191+ * operational if the retry timeout is elapsed.
192+ * The worker might still be unusable, but we try
193+ * anyway.
194+ */
195+ ap_proxy_retry_worker ("BALANCER" , worker , r -> server );
196+ if (PROXY_WORKER_IS_USABLE (worker )) {
197+ return worker ;
198+ } else {
199+ /*
200+ * We have a worker that is unusable.
201+ * It can be in error or disabled, but in case
202+ * it has a redirection set use that redirection worker.
203+ * This enables to safely remove the member from the
204+ * balancer. Of course you will need some kind of
205+ * session replication between those two remote.
206+ */
207+ if (* worker -> s -> redirect ) {
208+ proxy_worker * rworker = NULL ;
209+ rworker = find_route_worker (balancer , worker -> s -> redirect , r );
210+ /* Check if the redirect worker is usable */
211+ if (rworker && !PROXY_WORKER_IS_USABLE (rworker )) {
212+ /*
213+ * If the worker is in error state run
214+ * retry on that worker. It will be marked as
215+ * operational if the retry timeout is elapsed.
216+ * The worker might still be unusable, but we try
217+ * anyway.
218+ */
219+ ap_proxy_retry_worker ("BALANCER" , rworker , r -> server );
220+ }
221+ if (rworker && PROXY_WORKER_IS_USABLE (rworker ))
222+ return rworker ;
223+ }
224+ }
225+ }
226+ }
179227 }
180- worker ++ ;
228+ checked_standby = checking_standby ++ ;
181229 }
182230 return NULL ;
183231}
@@ -210,42 +258,7 @@ static proxy_worker *find_session_route(proxy_balancer *balancer,
210258 /* We have a route in path or in cookie
211259 * Find the worker that has this route defined.
212260 */
213- worker = find_route_worker (balancer , * route );
214- if (worker && !PROXY_WORKER_IS_USABLE (worker )) {
215- /*
216- * If the worker is in error state run
217- * retry on that worker. It will be marked as
218- * operational if the retry timeout is elapsed.
219- * The worker might still be unusable, but we try
220- * anyway.
221- */
222- ap_proxy_retry_worker ("BALANCER" , worker , r -> server );
223- if (!PROXY_WORKER_IS_USABLE (worker )) {
224- /*
225- * We have a worker that is unusable.
226- * It can be in error or disabled, but in case
227- * it has a redirection set use that redirection worker.
228- * This enables to safely remove the member from the
229- * balancer. Of course you will need some kind of
230- * session replication between those two remote.
231- */
232- if (* worker -> s -> redirect )
233- worker = find_route_worker (balancer , worker -> s -> redirect );
234- /* Check if the redirect worker is usable */
235- if (worker && !PROXY_WORKER_IS_USABLE (worker )) {
236- /*
237- * If the worker is in error state run
238- * retry on that worker. It will be marked as
239- * operational if the retry timeout is elapsed.
240- * The worker might still be unusable, but we try
241- * anyway.
242- */
243- ap_proxy_retry_worker ("BALANCER" , worker , r -> server );
244- if (!PROXY_WORKER_IS_USABLE (worker ))
245- worker = NULL ;
246- }
247- }
248- }
261+ worker = find_route_worker (balancer , * route , r );
249262 return worker ;
250263 }
251264 else
@@ -370,6 +383,9 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
370383 for (i = 0 ; i < (* balancer )-> workers -> nelts ; i ++ ) {
371384 /* Take into calculation only the workers that are
372385 * not in error state or not disabled.
386+ *
387+ * TODO: Abstract the below, since this is dependent
388+ * on the LB implementation
373389 */
374390 if (PROXY_WORKER_IS_USABLE (workers )) {
375391 workers -> s -> lbstatus += workers -> s -> lbfactor ;
@@ -662,12 +678,16 @@ static int balancer_handler(request_rec *r)
662678 ap_rvputs (r , "</td><td>" , worker -> s -> redirect , NULL );
663679 ap_rprintf (r , "</td><td>%d</td><td>" , worker -> s -> lbfactor );
664680 if (worker -> s -> status & PROXY_WORKER_DISABLED )
665- ap_rputs ("Dis" , r );
666- else if (worker -> s -> status & PROXY_WORKER_IN_ERROR )
667- ap_rputs ("Err" , r );
668- else if (worker -> s -> status & PROXY_WORKER_INITIALIZED )
681+ ap_rputs ("Dis " , r );
682+ if (worker -> s -> status & PROXY_WORKER_IN_ERROR )
683+ ap_rputs ("Err " , r );
684+ if (worker -> s -> status & PROXY_WORKER_STOPPED )
685+ ap_rputs ("Stop " , r );
686+ if (worker -> s -> status & PROXY_WORKER_HOT_STANDBY )
687+ ap_rputs ("Stby " , r );
688+ if (PROXY_WORKER_IS_USABLE (worker ))
669689 ap_rputs ("Ok" , r );
670- else
690+ if (! PROXY_WORKER_IS_INITIALIZED ( worker ))
671691 ap_rputs ("-" , r );
672692 ap_rputs ("</td></tr>\n" , r );
673693
@@ -817,34 +837,40 @@ static proxy_worker *find_best_byrequests(proxy_balancer *balancer,
817837{
818838 int i ;
819839 int total_factor = 0 ;
820- proxy_worker * worker = ( proxy_worker * ) balancer -> workers -> elts ;
840+ proxy_worker * worker ;
821841 proxy_worker * mycandidate = NULL ;
822-
823-
842+ int checking_standby = 0 ;
843+ int checked_standby = 0 ;
844+
824845 ap_log_error (APLOG_MARK , APLOG_DEBUG , 0 , r -> server ,
825846 "proxy: Entering byrequests for BALANCER (%s)" ,
826847 balancer -> name );
827848
828849 /* First try to see if we have available candidate */
829- for (i = 0 ; i < balancer -> workers -> nelts ; i ++ ) {
830- /* If the worker is in error state run
831- * retry on that worker. It will be marked as
832- * operational if the retry timeout is elapsed.
833- * The worker might still be unusable, but we try
834- * anyway.
835- */
836- if (!PROXY_WORKER_IS_USABLE (worker ))
837- ap_proxy_retry_worker ("BALANCER" , worker , r -> server );
838- /* Take into calculation only the workers that are
839- * not in error state or not disabled.
840- */
841- if (PROXY_WORKER_IS_USABLE (worker )) {
842- worker -> s -> lbstatus += worker -> s -> lbfactor ;
843- total_factor += worker -> s -> lbfactor ;
844- if (!mycandidate || worker -> s -> lbstatus > mycandidate -> s -> lbstatus )
845- mycandidate = worker ;
850+ while (!mycandidate && !checked_standby ) {
851+ worker = (proxy_worker * )balancer -> workers -> elts ;
852+ for (i = 0 ; i < balancer -> workers -> nelts ; i ++ , worker ++ ) {
853+ if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY (worker ) : PROXY_WORKER_IS_STANDBY (worker )) )
854+ continue ;
855+ /* If the worker is in error state run
856+ * retry on that worker. It will be marked as
857+ * operational if the retry timeout is elapsed.
858+ * The worker might still be unusable, but we try
859+ * anyway.
860+ */
861+ if (!PROXY_WORKER_IS_USABLE (worker ))
862+ ap_proxy_retry_worker ("BALANCER" , worker , r -> server );
863+ /* Take into calculation only the workers that are
864+ * not in error state or not disabled.
865+ */
866+ if (PROXY_WORKER_IS_USABLE (worker )) {
867+ worker -> s -> lbstatus += worker -> s -> lbfactor ;
868+ total_factor += worker -> s -> lbfactor ;
869+ if (!mycandidate || worker -> s -> lbstatus > mycandidate -> s -> lbstatus )
870+ mycandidate = worker ;
871+ }
846872 }
847- worker ++ ;
873+ checked_standby = checking_standby ++ ;
848874 }
849875
850876 if (mycandidate ) {
@@ -878,35 +904,42 @@ static proxy_worker *find_best_bytraffic(proxy_balancer *balancer,
878904 int i ;
879905 apr_off_t mytraffic = 0 ;
880906 apr_off_t curmin = 0 ;
881- proxy_worker * worker = (proxy_worker * )balancer -> workers -> elts ;
907+ proxy_worker * worker ;
908+ int checking_standby = 0 ;
909+ int checked_standby = 0 ;
882910 proxy_worker * mycandidate = NULL ;
883911
884912 ap_log_error (APLOG_MARK , APLOG_DEBUG , 0 , r -> server ,
885913 "proxy: Entering bytraffic for BALANCER (%s)" ,
886914 balancer -> name );
887915
888916 /* First try to see if we have available candidate */
889- for (i = 0 ; i < balancer -> workers -> nelts ; i ++ ) {
890- /* If the worker is in error state run
891- * retry on that worker. It will be marked as
892- * operational if the retry timeout is elapsed.
893- * The worker might still be unusable, but we try
894- * anyway.
895- */
896- if (!PROXY_WORKER_IS_USABLE (worker ))
897- ap_proxy_retry_worker ("BALANCER" , worker , r -> server );
898- /* Take into calculation only the workers that are
899- * not in error state or not disabled.
900- */
901- if (PROXY_WORKER_IS_USABLE (worker )) {
902- mytraffic = (worker -> s -> transferred /worker -> s -> lbfactor ) +
903- (worker -> s -> read /worker -> s -> lbfactor );
904- if (!mycandidate || mytraffic < curmin ) {
905- mycandidate = worker ;
906- curmin = mytraffic ;
917+ while (!mycandidate && !checked_standby ) {
918+ worker = (proxy_worker * )balancer -> workers -> elts ;
919+ for (i = 0 ; i < balancer -> workers -> nelts ; i ++ , worker ++ ) {
920+ if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY (worker ) : PROXY_WORKER_IS_STANDBY (worker )) )
921+ continue ;
922+ /* If the worker is in error state run
923+ * retry on that worker. It will be marked as
924+ * operational if the retry timeout is elapsed.
925+ * The worker might still be unusable, but we try
926+ * anyway.
927+ */
928+ if (!PROXY_WORKER_IS_USABLE (worker ))
929+ ap_proxy_retry_worker ("BALANCER" , worker , r -> server );
930+ /* Take into calculation only the workers that are
931+ * not in error state or not disabled.
932+ */
933+ if (PROXY_WORKER_IS_USABLE (worker )) {
934+ mytraffic = (worker -> s -> transferred /worker -> s -> lbfactor ) +
935+ (worker -> s -> read /worker -> s -> lbfactor );
936+ if (!mycandidate || mytraffic < curmin ) {
937+ mycandidate = worker ;
938+ curmin = mytraffic ;
939+ }
907940 }
908941 }
909- worker ++ ;
942+ checked_standby = checking_standby ++ ;
910943 }
911944
912945 if (mycandidate ) {
0 commit comments