You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2004/08/12 01:05:59 UTC

cvs commit: httpd-2.0/modules/proxy mod_proxy.h proxy_balancer.c proxy_util.c

wrowe       2004/08/11 16:05:59

  Modified:    modules/proxy mod_proxy.h proxy_balancer.c proxy_util.c
  Log:
  Implement the worker retry functionality.
  It uses either worker->retry option or default 60 second retry
  that is on each revolution extended by another 60 seconds.
  
  Submitted by: mturk
  
  Revision  Changes    Path
  1.119     +1 -0      httpd-2.0/modules/proxy/mod_proxy.h
  
  Index: mod_proxy.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/proxy/mod_proxy.h,v
  retrieving revision 1.118
  retrieving revision 1.119
  diff -u -r1.118 -r1.119
  --- mod_proxy.h	11 Aug 2004 23:02:53 -0000	1.118
  +++ mod_proxy.h	11 Aug 2004 23:05:59 -0000	1.119
  @@ -384,6 +384,7 @@
   PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, proxy_server_conf *conf, proxy_worker *worker, proxy_conn_rec *conn,
                                                    apr_pool_t *ppool, apr_uri_t *uri, char **url, const char *proxyname, apr_port_t proxyport,
                                                    char *server_portstr, int server_portstr_size);
  +PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worker, server_rec *s);
   PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, proxy_conn_rec **conn, proxy_worker *worker, server_rec *s);
   PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, proxy_conn_rec *conn, server_rec *s);
   PROXY_DECLARE(apr_status_t) ap_proxy_close_connection(proxy_conn_rec *conn);
  
  
  
  1.6       +7 -4      httpd-2.0/modules/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/proxy/proxy_balancer.c,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- proxy_balancer.c	11 Aug 2004 23:03:43 -0000	1.5
  +++ proxy_balancer.c	11 Aug 2004 23:05:59 -0000	1.6
  @@ -146,11 +146,14 @@
   
       /* First try to see if we have available candidate */
       for (i = 0; i < balancer->workers->nelts; i++) {
  -        /* If the worker is not error state
  -         * or not in disabled mode
  +        /* See if the retry timeout is ellapsed
  +         * for the workers flagged as IN_ERROR
  +         */
  +        if (!PROXY_WORKER_IS_USABLE(worker->w))
  +            ap_proxy_retry_worker("BALANCER", worker->w, r->server)
  +        /* If the worker is not in error state
  +         * or not disabled.
            */
  -
  -        /* TODO: read the scoreboard status */
           if (PROXY_WORKER_IS_USABLE(worker->w)) {
               if (!candidate)
                   candidate = worker;
  
  
  
  1.131     +47 -2     httpd-2.0/modules/proxy/proxy_util.c
  
  Index: proxy_util.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/proxy/proxy_util.c,v
  retrieving revision 1.130
  retrieving revision 1.131
  diff -u -r1.130 -r1.131
  --- proxy_util.c	11 Aug 2004 23:02:53 -0000	1.130
  +++ proxy_util.c	11 Aug 2004 23:05:59 -0000	1.131
  @@ -1471,6 +1471,31 @@
       return rv;
   }
   
  +PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function,
  +                                         proxy_worker *worker,
  +                                         server_rec *s)
  +{
  +    if (worker->status & PROXY_WORKER_IN_ERROR) {
  +        apr_interval_time_t diff;
  +        apr_time_t now = apr_time_now();
  +        if (worker->retry)
  +            diff = worker->retry;
  +        else
  +            diff = apr_time_from_sec(60 + 60 * worker->retries++);
  +        if (now > worker->error_time + diff) {
  +            worker->status &= ~PROXY_WORKER_IN_ERROR;
  +            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
  +                         "proxy: %s: retrying the worker for (%s)",
  +                         proxy_function, worker->hostname);
  +            return OK;
  +        }
  +        else
  +            return DECLINED;
  +    }
  +    else
  +        return OK;
  +}
  +
   PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
                                                  proxy_conn_rec **conn,
                                                  proxy_worker *worker,
  @@ -1483,10 +1508,22 @@
               ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                            "proxy: %s: failed to initialize worker for (%s)",
                            proxy_function, worker->hostname);
  -            return DECLINED;
  +            return HTTP_INTERNAL_SERVER_ERROR;
           }
           worker->status = PROXY_WORKER_INITIALIZED;
       }
  +
  +    if (!PROXY_WORKER_IS_USABLE(worker)) {
  +        /* Retry the worker */
  +        ap_proxy_retry_worker(proxy_function, worker, s);
  +    
  +        if (!PROXY_WORKER_IS_USABLE(worker)) {
  +            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
  +                         "proxy: %s: disabled connection for (%s)",
  +                         proxy_function, worker->hostname);
  +            return HTTP_SERVICE_UNAVAILABLE;
  +        }
  +    }
   #if APR_HAS_THREADS
       if (worker->hmax) {
           rv = apr_reslist_acquire(worker->cp->res, (void **)conn);
  @@ -1508,7 +1545,7 @@
           ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                        "proxy: %s: failed to acquire connection for (%s)",
                        proxy_function, worker->hostname);
  -        return DECLINED;
  +        return HTTP_SERVICE_UNAVAILABLE;
       }
       return OK;
   }
  @@ -1722,6 +1759,14 @@
           conn->sock   = newsock;
           conn->worker = worker;
           connected    = 1;
  +    }
  +    /* Put the entire worker to error state
  +     * Altrough some connections may be alive
  +     * no further connections to the worker could be made
  +     */
  +    if (!connected && PROXY_WORKER_IS_USABLE(worker)) {
  +        worker->status |= PROXY_WORKER_IN_ERROR;
  +        worker->error_time = apr_time_now();
       }
       return connected ? OK : DECLINED;
   }