mturk       2005/03/26 00:44:11

  Modified:    jk/native/common jk_lb_worker.c
  Log:
  In case ajp13 worker returns client error do not mark the worker
  in error state. This operation is not recoverable, so return BAD_REQUEST
  to web server.
  
  Revision  Changes    Path
  1.73      +50 -24    jakarta-tomcat-connectors/jk/native/common/jk_lb_worker.c
  
  Index: jk_lb_worker.c
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_lb_worker.c,v
  retrieving revision 1.72
  retrieving revision 1.73
  diff -u -r1.72 -r1.73
  --- jk_lb_worker.c    26 Feb 2005 07:16:54 -0000      1.72
  +++ jk_lb_worker.c    26 Mar 2005 08:44:11 -0000      1.73
  @@ -28,15 +28,16 @@
   #include "jk_util.h"
   #include "jk_worker.h"
   #include "jk_lb_worker.h"
  +#include "jk_ajp13.h"
   #include "jk_mt.h"
   #include "jk_shm.h"
   
   /*
  - * The load balancing code in this 
  + * The load balancing code in this
    */
   
   
  -/* 
  +/*
    * Time to wait before retry...
    */
   #define JK_WORKER_IN_ERROR(w) ((w)->in_error_state && !(w)->is_disabled && 
!(w)->is_busy)
  @@ -66,9 +67,9 @@
               if (strlen(id_start)) {
                   char *id_end;
                   id_start = jk_pool_strdup(s->pool, id_start);
  -                /* 
  +                /*
                    * The query string is not part of req_uri, however
  -                 * to be on the safe side lets remove the trailing query 
  +                 * to be on the safe side lets remove the trailing query
                    * string if appended...
                    */
                   if ((id_end = strchr(id_start, '?')) != NULL) {
  @@ -186,14 +187,14 @@
       JK_TRACE_EXIT(l);
   }
   
  -static worker_record_t *find_by_session(lb_worker_t *p, 
  +static worker_record_t *find_by_session(lb_worker_t *p,
                                           const char *name,
                                           jk_logger_t *l)
   {
   
       worker_record_t *rc = NULL;
       unsigned int i;
  -    
  +
       for (i = 0; i < p->num_of_workers; i++) {
           if (strcmp(p->lb_workers[i].s->name, name) == 0) {
               rc = &p->lb_workers[i];
  @@ -214,7 +215,7 @@
       size_t curmin = 0;
   
       worker_record_t *candidate = NULL;
  -    
  +
       /* First try to see if we have available candidate */
       for (i = 0; i < p->num_of_workers; i++) {
           /* Skip all workers that are not member of domain */
  @@ -258,7 +259,7 @@
       unsigned int i;
       int total_factor = 0;
       worker_record_t *candidate = NULL;
  -    
  +
       /* First try to see if we have available candidate */
       for (i = 0; i < p->num_of_workers; i++) {
           /* If the worker is in error state run
  @@ -286,14 +287,14 @@
       return candidate;
   }
   
  -static worker_record_t *find_best_bytraffic(lb_worker_t *p, 
  +static worker_record_t *find_best_bytraffic(lb_worker_t *p,
                                                jk_logger_t *l)
   {
       unsigned int i;
       size_t mytraffic = 0;
       size_t curmin = 0;
       worker_record_t *candidate = NULL;
  -    
  +
       /* First try to see if we have available candidate */
       for (i = 0; i < p->num_of_workers; i++) {
           /* If the worker is in error state run
  @@ -316,11 +317,11 @@
                   curmin = mytraffic;
               }
           }
  -    }    
  +    }
       return candidate;
   }
   
  -static worker_record_t *find_bysession_route(lb_worker_t *p, 
  +static worker_record_t *find_bysession_route(lb_worker_t *p,
                                                const char *name,
                                                jk_logger_t *l)
   {
  @@ -379,7 +380,7 @@
   {
       worker_record_t *rc = NULL;
       unsigned int i;
  -    const char *redirect = NULL;    
  +    const char *redirect = NULL;
   
       for (i = 0; i < p->num_of_workers; i++) {
           if (strlen(p->lb_workers[i].s->redirect)) {
  @@ -522,6 +523,7 @@
           lb_endpoint_t *p = e->endpoint_private;
           int attempt = 0;
           int num_of_workers = p->worker->num_of_workers;
  +        worker_record_t *prec = NULL;
           /* Set returned error to OK */
           *is_error = JK_HTTP_OK;
   
  @@ -539,12 +541,14 @@
               worker_record_t *rec =
                   get_most_suitable_worker(p->worker, s, attempt++, l);
               int rc;
  -
  -            if (rec) {
  +            /* Do not reuse previous worker, because
  +             * that worker already failed.
  +             */
  +            if (rec && rec != prec) {
                   int is_service_error = JK_HTTP_OK;
  -                int service_ok = JK_FALSE;
  +                int service_stat = JK_FALSE;
                   jk_endpoint_t *end = NULL;
  -                
  +
                   s->jvm_route = rec->r;
                   rc = rec->w->get_endpoint(rec->w, &end, l);
   
  @@ -561,7 +565,7 @@
                       /* Increment the number of workers serving request */
                       p->worker->s->busy++;
                       rec->s->busy++;
  -                    service_ok = end->service(end, s, l, &is_service_error);
  +                    service_stat = end->service(end, s, l, 
&is_service_error);
                       /* Update partial reads and writes if any */
                       rec->s->readed += end->rd;
                       rec->s->transferred += end->wr;
  @@ -573,7 +577,7 @@
                       /* Decrement the busy worker count */
                       rec->s->busy--;
                       p->worker->s->busy--;
  -                    if (service_ok) {
  +                    if (service_stat == JK_TRUE) {
                           rec->s->in_error_state = JK_FALSE;
                           rec->s->in_recovering = JK_FALSE;
                           rec->s->error_time = 0;
  @@ -592,9 +596,10 @@
                              rec->s->name);
                       /* Decrement the worker count and try another worker */
                       --num_of_workers;
  +                    prec = rec;
                       continue;
                   }
  -                if (!service_ok) {
  +                if (service_stat == JK_FALSE) {
                       /*
                       * Service failed !!!
                       *
  @@ -623,6 +628,26 @@
                              "service failed, worker %s is in error state",
                              rec->s->name);
                   }
  +                else if (service_stat == JK_CLIENT_ERROR) {
  +                    /*
  +                    * Clent error !!!
  +                    * Since this is bad request do not fail over.
  +                    */
  +                    is_service_error = JK_HTTP_BAD_REQUEST;
  +                    rec->s->errors++;
  +                    rec->s->in_error_state = JK_FALSE;
  +                    rec->s->in_recovering = JK_FALSE;
  +                    rec->s->error_time = 0;
  +                    *is_error = is_service_error;
  +
  +                    jk_log(l, JK_LOG_INFO,
  +                           "unrecoverable error %d, request failed."
  +                           " Client failed in the middle of request,"
  +                           " we can't recover to another instance.",
  +                           is_service_error);
  +                    JK_TRACE_EXIT(l);
  +                    return JK_CLIENT_ERROR;
  +                }
                   else {
                       /* If we can not get the endpoint from the worker
                        * that does not mean that the worker is in error
  @@ -630,9 +655,8 @@
                        * We will try another worker.
                        * To prevent infinite loop decrement worker count;
                        */
  -                    --num_of_workers;
                   }
  -                /* 
  +                /*
                    * Error is recoverable by submitting the request to
                    * another worker... Lets try to do that.
                    */
  @@ -648,6 +672,8 @@
                   *is_error = JK_HTTP_SERVER_ERROR;
                   return JK_FALSE;
               }
  +            --num_of_workers;
  +            prec = rec;
           }
           jk_log(l, JK_LOG_INFO,
                  "All tomcat instances are busy or in error state");
  @@ -716,7 +742,7 @@
               for (i = 0; i < num_of_workers; i++) {
                   p->lb_workers[i].s = jk_shm_alloc_worker(&p->p);
                   if (p->lb_workers[i].s == NULL) {
  -                    jk_log(l, JK_LOG_ERROR, 
  +                    jk_log(l, JK_LOG_ERROR,
                              "allocating worker record from shared memory");
                       JK_TRACE_EXIT(l);
                       return JK_FALSE;
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to