You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by rj...@apache.org on 2008/01/13 18:54:26 UTC
svn commit: r611609 - in /tomcat/connectors/trunk/jk/native/common:
jk_ajp_common.c jk_ajp_common.h
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: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org