Author: rjung Date: Sun Jan 13 09:54:25 2008 New Revision: 611609 URL: http://svn.apache.org/viewvc?rev=611609&view=rev Log: Introduce ajp shm worker to common ajp worker.
Modified: tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c tomcat/connectors/trunk/jk/native/common/jk_ajp_common.h Modified: tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c?rev=611609&r1=611608&r2=611609&view=diff ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c (original) +++ tomcat/connectors/trunk/jk/native/common/jk_ajp_common.c Sun Jan 13 09:54:25 2008 @@ -61,6 +61,15 @@ return rc; } +static const char *ajp_state_type[] = { + JK_AJP_STATE_TEXT_IDLE, + JK_AJP_STATE_TEXT_OK, + JK_AJP_STATE_TEXT_ERROR, + JK_AJP_STATE_TEXT_PROBE, + "unknown", + NULL +}; + #define UNKNOWN_METHOD (-1) static int sc_for_req_method(const char *method, size_t len) @@ -330,6 +339,30 @@ /* NOTREACHED */ } +/* Return the string representation of the worker state */ +const char *jk_ajp_get_state(ajp_worker_t *aw, jk_logger_t *l) +{ + return ajp_state_type[aw->s->state]; +} + +/* Return the int representation of the worker state */ +int jk_ajp_get_state_code(const char *v) +{ + if (!v) + return JK_AJP_STATE_DEF; + else if (*v == 'i' || *v == 'I' || *v == 'n' || *v == 'N' || *v == '0') + return JK_AJP_STATE_IDLE; + else if (*v == 'o' || *v == 'O' || *v == '1') + return JK_AJP_STATE_OK; + else if (*v == 'e' || *v == 'E' || *v == '4') + return JK_AJP_STATE_ERROR; + else if (*v == 'p' || *v == 'P' || *v == '6') + return JK_AJP_STATE_PROBE; + else + return JK_AJP_STATE_DEF; +} + + /* * Message structure @@ -1931,6 +1964,21 @@ return JK_FALSE; } +static void ajp_update_stats(jk_endpoint_t *e, ajp_worker_t *aw, int rc, jk_logger_t *l) +{ + aw->s->readed += e->rd; + aw->s->transferred += e->wr; + if (aw->s->busy) + aw->s->busy--; + if (rc != JK_TRUE) { + aw->s->state = JK_AJP_STATE_ERROR; + aw->s->errors++; + aw->s->error_time = time(NULL); + } + else + aw->s->state = JK_AJP_STATE_OK; +} + /* * service is now splitted in ajp_send_request and ajp_get_reply * much more easier to do errors recovery @@ -1976,6 +2024,7 @@ ajp_operation_t oper; ajp_operation_t *op = &oper; ajp_endpoint_t *p; + ajp_worker_t *aw; int log_error; int rc = JK_UNSET; char *msg; @@ -1991,6 +2040,9 @@ } p = e->endpoint_private; + aw = p->worker; + + aw->s->used++; /* Set returned error to SERVER ERROR */ *is_error = JK_HTTP_SERVER_ERROR; @@ -2002,7 +2054,7 @@ JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } - if (jk_b_set_buffer_size(op->request, p->worker->max_packet_size)) { + if (jk_b_set_buffer_size(op->request, aw->max_packet_size)) { jk_log(l, JK_LOG_ERROR, "Failed allocating AJP message buffer"); JK_TRACE_EXIT(l); @@ -2017,7 +2069,7 @@ JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } - if (jk_b_set_buffer_size(op->reply, p->worker->max_packet_size)) { + if (jk_b_set_buffer_size(op->reply, aw->max_packet_size)) { jk_log(l, JK_LOG_ERROR, "Failed allocating AJP message buffer"); JK_TRACE_EXIT(l); @@ -2032,7 +2084,7 @@ JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } - if (jk_b_set_buffer_size(op->post, p->worker->max_packet_size)) { + if (jk_b_set_buffer_size(op->post, aw->max_packet_size)) { jk_log(l, JK_LOG_ERROR, "Failed allocating AJP message buffer"); JK_TRACE_EXIT(l); @@ -2049,7 +2101,7 @@ p->left_bytes_to_send = s->content_length; p->reuse = JK_FALSE; - s->secret = p->worker->secret; + s->secret = aw->secret; /* * We get here initial request (in op->request) @@ -2059,15 +2111,21 @@ jk_log(l, JK_LOG_INFO, "Creating AJP message failed, " "without recovery"); + aw->s->client_errors++; JK_TRACE_EXIT(l); return JK_CLIENT_ERROR; } if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "processing %s with %d retries", - p->worker->name, p->worker->retries); + aw->name, aw->retries); } - for (i = 0; i < p->worker->retries; i++) { + aw->s->busy++; + if (aw->s->state == JK_AJP_STATE_ERROR) + aw->s->state = JK_AJP_STATE_PROBE; + if (aw->s->busy > aw->s->max_busy) + aw->s->max_busy = aw->s->busy; + for (i = 0; i < aw->retries; i++) { /* * We're using op->request which hold initial request * if Tomcat is stopped or restarted, we will pass op->request @@ -2081,6 +2139,7 @@ if (err == JK_CLIENT_RD_ERROR) { *is_error = JK_HTTP_BAD_REQUEST; msg = "because of client read error"; + aw->s->client_errors++; rc = JK_CLIENT_ERROR; log_error = JK_FALSE; e->recoverable = JK_FALSE; @@ -2088,7 +2147,7 @@ /* This doesn't make sense, because we already set reuse */ /* to JK_FALSE at the beginning of service() and only set it to true again after */ /* the whole response has beend received (callback JK_AJP13_END_RESPONSE). */ -// if (p->worker->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { +// if (aw->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { // /* Mark the endpoint for shutdown */ // p->reuse = JK_FALSE; // } @@ -2110,6 +2169,7 @@ if (err == JK_TRUE) { *is_error = JK_HTTP_OK; /* Done with the request */ + ajp_update_stats(e, aw, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_TRUE; } @@ -2117,6 +2177,7 @@ if (err == JK_CLIENT_RD_ERROR) { *is_error = JK_HTTP_BAD_REQUEST; msg = "because of client read error"; + aw->s->client_errors++; rc = JK_CLIENT_ERROR; log_error = JK_FALSE; e->recoverable = JK_FALSE; @@ -2124,7 +2185,7 @@ /* This doesn't make sense, because we already set reuse */ /* to JK_FALSE at the beginning of service() and only set it to true again after */ /* the whole response has beend received (callback JK_AJP13_END_RESPONSE). */ -// if (p->worker->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { +// if (aw->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { // /* Mark the endpoint for shutdown */ // p->reuse = JK_FALSE; // } @@ -2133,6 +2194,7 @@ /* XXX: Is this correct to log this as 200? */ *is_error = JK_HTTP_OK; msg = "because of client write error"; + aw->s->client_errors++; rc = JK_CLIENT_ERROR; log_error = JK_FALSE; e->recoverable = JK_FALSE; @@ -2140,7 +2202,7 @@ /* This doesn't make sense, because we already set reuse */ /* to JK_FALSE at the beginning of service() and only set it to true again after */ /* the whole response has beend received (callback JK_AJP13_END_RESPONSE). */ -// if (p->worker->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { +// if (aw->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { // /* Mark the endpoint for shutdown */ // p->reuse = JK_FALSE; // } @@ -2153,6 +2215,7 @@ else if (err == JK_REPLY_TIMEOUT) { *is_error = JK_HTTP_GATEWAY_TIME_OUT; msg = "because of reply timeout"; + aw->s->reply_timeouts++; rc = err; } else if (err == JK_STATUS_ERROR || err == JK_STATUS_FATAL_ERROR) { @@ -2190,25 +2253,26 @@ rc = JK_FATAL_ERROR; jk_log(l, JK_LOG_ERROR, "(%s) unexpected condition err=%d recoverable=%d", - p->worker->name, err, op->recoverable); + aw->name, err, op->recoverable); } if (!op->recoverable && log_error == JK_TRUE) { jk_log(l, JK_LOG_ERROR, "(%s) sending request to tomcat failed (unrecoverable), " "%s " "(attempt=%d)", - p->worker->name, msg, i + 1); + aw->name, msg, i + 1); } else { jk_log(l, JK_LOG_INFO, "(%s) sending request to tomcat failed (%srecoverable), " "%s " "(attempt=%d)", - p->worker->name, + aw->name, op->recoverable ? "" : "un", msg, i + 1); } if (!op->recoverable) { + ajp_update_stats(e, aw, rc, l); JK_TRACE_EXIT(l); return rc; } @@ -2221,10 +2285,11 @@ jk_log(l, JK_LOG_ERROR, "(%s) Connecting to tomcat failed. Tomcat is probably not started " "or is listening on the wrong port", - p->worker->name); + aw->name); /* XXX: Do we need to fix rc or is_error before returning? */ + ajp_update_stats(e, aw, rc, l); JK_TRACE_EXIT(l); return rc; } @@ -2394,6 +2459,11 @@ p->retries = JK_RETRIES; } + p->maintain_time = jk_get_worker_maintain_time(props); + if(p->maintain_time < 0) + p->maintain_time = 0; + p->s->last_maintain_time = time(NULL); + if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, @@ -2509,6 +2579,15 @@ *w = &aw->worker; + aw->s = jk_shm_alloc_ajp_worker(&aw->p); + if (!aw->s) { + jk_close_pool(&aw->p); + free(aw); + jk_log(l, JK_LOG_ERROR, + "allocating ajp worker record from shared memory"); + JK_TRACE_EXIT(l); + return JK_FALSE; + } JK_TRACE_EXIT(l); return JK_TRUE; } @@ -2676,6 +2755,27 @@ if (pThis && pThis->worker_private) { ajp_worker_t *aw = pThis->worker_private; int rc; + long delta; + + jk_shm_lock(); + + /* Now we check for global maintenance (once for all processes). + * Checking workers for idleness. + * Therefore we globally sync and we use a global timestamp. + * Since it's possible that we come here a few milliseconds + * before the interval has passed, we allow a little tolerance. + */ + delta = (long)difftime(now, aw->s->last_maintain_time) + JK_AJP_MAINTAIN_TOLERANCE; + if (delta >= aw->maintain_time) { + aw->s->last_maintain_time = now; + if (aw->s->state == JK_AJP_STATE_OK && + aw->s->used == aw->s->used_snapshot) + aw->s->state = JK_AJP_STATE_IDLE; + aw->s->used_snapshot = aw->s->used; + } + + jk_shm_unlock(); + /* Obtain current time only if needed */ if (aw->cache_timeout <= 0) { /* Nothing to do. */ Modified: tomcat/connectors/trunk/jk/native/common/jk_ajp_common.h URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_ajp_common.h?rev=611609&r1=611608&r2=611609&view=diff ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_ajp_common.h (original) +++ tomcat/connectors/trunk/jk/native/common/jk_ajp_common.h Sun Jan 13 09:54:25 2008 @@ -35,6 +35,22 @@ { #endif /* __cplusplus */ +#define JK_AJP_STATE_IDLE (0) +#define JK_AJP_STATE_OK (1) +#define JK_AJP_STATE_ERROR (2) +#define JK_AJP_STATE_PROBE (3) +#define JK_AJP_STATE_DEF (JK_AJP_STATE_IDLE) +#define JK_AJP_STATE_TEXT_IDLE ("OK/IDLE") +#define JK_AJP_STATE_TEXT_OK ("OK") +#define JK_AJP_STATE_TEXT_ERROR ("ERR") +#define JK_AJP_STATE_TEXT_PROBE ("ERR/PRB") +#define JK_AJP_STATE_TEXT_MAX (JK_AJP_STATE_PROBE) +#define JK_AJP_STATE_TEXT_DEF (JK_AJP_STATE_TEXT_IDLE) + +/* We accept doing global maintenance if we are */ +/* JK_AJP_MAINTAIN_TOLERANCE seconds early. */ +#define JK_AJP_MAINTAIN_TOLERANCE (2) + /* * Conditional request attributes * @@ -234,8 +250,14 @@ struct ajp_worker { jk_worker_t worker; + /* Shared memory worker data */ + jk_shm_ajp_worker_t *s; char name[JK_SHM_STR_SIZ+1]; + /* Sequence counter starting at 0 and increasing + * every time we change the config + */ + volatile unsigned int sequence; jk_pool_t p; jk_pool_atom_t buf[TINY_POOL_SIZE]; @@ -246,6 +268,7 @@ unsigned connect_retry_attempts; const char *host; int port; + int maintain_time; /* * Open connections cache... * @@ -353,6 +376,10 @@ * Functions */ + +const char *jk_ajp_get_state(ajp_worker_t *aw, jk_logger_t *l); + +int jk_ajp_get_state_code(const char *v); int ajp_validate(jk_worker_t *pThis, jk_map_t *props, --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]