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]