On 04/11/2018 02:11 PM, [email protected] wrote:
> Author: jhriggs
> Date: Wed Apr 11 12:11:05 2018
> New Revision: 1828890
> 
> URL: http://svn.apache.org/viewvc?rev=1828890&view=rev
> Log:
> mod_proxy_balancer: Add hot spare member type and corresponding flag (R). Hot 
> spare members are
> used as drop-in replacements for unusable workers in the same load balancer 
> set. This differs
> from hot standbys which are only used when all workers in a set are unusable. 
> PR 61140.
> 
> Modified:
>     httpd/httpd/trunk/CHANGES
>     httpd/httpd/trunk/docs/log-message-tags/next-number
>     httpd/httpd/trunk/docs/manual/howto/reverse_proxy.xml
>     httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml
>     httpd/httpd/trunk/modules/proxy/balancers/mod_lbmethod_bybusyness.c
>     httpd/httpd/trunk/modules/proxy/balancers/mod_lbmethod_byrequests.c
>     httpd/httpd/trunk/modules/proxy/balancers/mod_lbmethod_bytraffic.c
>     httpd/httpd/trunk/modules/proxy/mod_proxy.c
>     httpd/httpd/trunk/modules/proxy/mod_proxy.h
>     httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
>     httpd/httpd/trunk/modules/proxy/proxy_util.c
> 

> Modified: httpd/httpd/trunk/modules/proxy/proxy_util.c
> URL: 
> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/proxy_util.c?rev=1828890&r1=1828889&r2=1828890&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/proxy/proxy_util.c (original)
> +++ httpd/httpd/trunk/modules/proxy/proxy_util.c Wed Apr 11 12:11:05 2018

> @@ -1293,6 +1294,121 @@ PROXY_DECLARE(apr_status_t) ap_proxy_ini
>      return APR_SUCCESS;
>  }
>  
> +PROXY_DECLARE(proxy_worker *) 
> ap_proxy_balancer_get_best_worker(proxy_balancer *balancer,
> +                                                                request_rec 
> *r,
> +                                                                
> proxy_is_best_callback_fn_t *is_best,
> +                                                                void *baton)
> +{
> +    int i = 0;
> +    int cur_lbset = 0;
> +    int max_lbset = 0;
> +    int unusable_workers = 0;
> +    apr_pool_t *tpool = NULL;
> +    apr_array_header_t *spares = NULL;
> +    apr_array_header_t *standbys = NULL;
> +    proxy_worker *worker = NULL;
> +    proxy_worker *best_worker = NULL;
> +
> +    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(10122)
> +                 "proxy: Entering %s for BALANCER (%s)",
> +                 balancer->lbmethod->name, balancer->s->name);
> +
> +    apr_pool_create(&tpool, r->pool);
> +
> +    spares = apr_array_make(tpool, 1, sizeof(proxy_worker*));
> +    standbys = apr_array_make(tpool, 1, sizeof(proxy_worker*));
> +
> +    /* Process lbsets in order, only replacing unusable workers in a given 
> lbset
> +     * with available spares from the same lbset. Hot standbys will be used 
> as a
> +     * last resort when all other workers and spares are unavailable.
> +     */
> +    for (cur_lbset = 0; !best_worker && (cur_lbset <= max_lbset); 
> cur_lbset++) {
> +        unusable_workers = 0;
> +        apr_array_clear(spares);
> +        apr_array_clear(standbys);
> +
> +        for (i = 0; i < balancer->workers->nelts; i++) {
> +            worker = APR_ARRAY_IDX(balancer->workers, i, proxy_worker *);
> +
> +            if (worker->s->lbset > max_lbset) {
> +                max_lbset = worker->s->lbset;
> +            }
> +
> +            if (worker->s->lbset != cur_lbset) {
> +                continue;
> +            }
> +
> +            /* A draining worker that is neither a spare nor a standby 
> should be
> +             * considered unusable to be replaced by spares.
> +             */
> +            if (PROXY_WORKER_IS_DRAINING(worker)) {
> +                if (!PROXY_WORKER_IS_SPARE(worker) && 
> !PROXY_WORKER_IS_STANDBY(worker)) {
> +                    unusable_workers++;
> +                }
> +
> +                continue;
> +            }
> +
> +            /* If the worker is in error state run retry on that worker. It 
> will
> +             * be marked as operational if the retry timeout is elapsed.  The
> +             * worker might still be unusable, but we try anyway.
> +             */
> +            if (!PROXY_WORKER_IS_USABLE(worker)) {
> +                ap_proxy_retry_worker("BALANCER", worker, r->server);
> +            }
> +
> +            if (PROXY_WORKER_IS_SPARE(worker)) {
> +                if (PROXY_WORKER_IS_USABLE(worker)) {
> +                    APR_ARRAY_PUSH(spares, proxy_worker *) = worker;
> +                }
> +            }
> +            else if (PROXY_WORKER_IS_STANDBY(worker)) {
> +                if (PROXY_WORKER_IS_USABLE(worker)) {
> +                    APR_ARRAY_PUSH(standbys, proxy_worker *) = worker;
> +                }
> +            }
> +            else if (PROXY_WORKER_IS_USABLE(worker)) {
> +              if (is_best(worker, best_worker, baton)) {
> +                best_worker = worker;
> +              }
> +            }
> +            else {
> +                unusable_workers++;
> +            }
> +        }
> +
> +        /* Check if any spares are best. */
> +        for (i = 0; (i < spares->nelts) && (i < unusable_workers); i++) {

Couldn't we save MIN(spares->nelts, unusable_workers) before the loop and check 
that i < MIN in the loop?

Regards

RĂ¼diger

Reply via email to