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 2015/01/07 17:15:29 UTC

svn commit: r1650098 - in /tomcat/jk/trunk: native/common/ xdocs/miscellaneous/ xdocs/reference/

Author: rjung
Date: Wed Jan  7 16:15:28 2015
New Revision: 1650098

URL: http://svn.apache.org/r1650098
Log:
BZ 44571: Implement an optional limit on concurrent
requests allowed for a worker
(attribute "busy_limit").

Original patch contributed by zealot0630 at
gmail dot com.

The feature is documented as being experimental.

Modified:
    tomcat/jk/trunk/native/common/jk_ajp13.h
    tomcat/jk/trunk/native/common/jk_ajp_common.c
    tomcat/jk/trunk/native/common/jk_ajp_common.h
    tomcat/jk/trunk/native/common/jk_lb_worker.c
    tomcat/jk/trunk/native/common/jk_shm.h
    tomcat/jk/trunk/native/common/jk_status.c
    tomcat/jk/trunk/native/common/jk_util.c
    tomcat/jk/trunk/native/common/jk_util.h
    tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
    tomcat/jk/trunk/xdocs/reference/status.xml
    tomcat/jk/trunk/xdocs/reference/workers.xml

Modified: tomcat/jk/trunk/native/common/jk_ajp13.h
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp13.h?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp13.h (original)
+++ tomcat/jk/trunk/native/common/jk_ajp13.h Wed Jan  7 16:15:28 2015
@@ -50,6 +50,7 @@ extern "C"
 #define JK_STATUS_FATAL_ERROR       (-9)
 #define JK_REPLY_TIMEOUT            (-10)
 #define JK_AJP_PROTOCOL_ERROR       (-11)
+#define JK_BUSY_ERROR               (-12)
 
 #define AJP13_DEF_TIMEOUT           (0) /* Idle timout for pooled connections */
 

Modified: tomcat/jk/trunk/native/common/jk_ajp_common.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.c?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp_common.c (original)
+++ tomcat/jk/trunk/native/common/jk_ajp_common.c Wed Jan  7 16:15:28 2015
@@ -1118,6 +1118,7 @@ void jk_ajp_pull(ajp_worker_t * aw, int
     aw->recovery_opts = aw->s->recovery_opts;
     aw->retries = aw->s->retries;
     aw->retry_interval = aw->s->retry_interval;
+    aw->busy_limit = aw->s->busy_limit;
     aw->max_packet_size = aw->s->max_packet_size;
     aw->sequence = aw->s->h.sequence;
     if (aw->addr_sequence != aw->s->addr_sequence) {
@@ -1187,6 +1188,7 @@ void jk_ajp_push(ajp_worker_t * aw, int
     aw->s->recovery_opts = aw->recovery_opts;
     aw->s->retries = aw->retries;
     aw->s->retry_interval = aw->retry_interval;
+    aw->s->busy_limit = aw->busy_limit;
     aw->s->max_packet_size = aw->max_packet_size;
     /* Force squence update on push
      */
@@ -2561,6 +2563,20 @@ static int JK_METHOD ajp_service(jk_endp
                aw->name, aw->retries);
     }
     busy = JK_ATOMIC_INCREMENT(&(aw->s->busy));
+    if (aw->busy_limit > 0 && busy > aw->busy_limit) {
+        JK_ATOMIC_DECREMENT(&(aw->s->busy));
+        e->recoverable = JK_TRUE;
+        aw->s->errors++;
+        aw->s->error_time = time(NULL);
+        *is_error = JK_HTTP_SERVER_BUSY;
+        rc = JK_BUSY_ERROR;
+        jk_log(l, JK_LOG_ERROR,
+               "(%s) sending request to tomcat failed (unrecoverable), "
+               "busy limit %d reached (rc=%d, errors=%d, client_errors=%d).",
+               aw->name, aw->busy_limit, rc, aw->s->errors, aw->s->client_errors);
+        JK_TRACE_EXIT(l);
+        return rc;
+    }
     if (aw->s->state == JK_AJP_STATE_ERROR)
         aw->s->state = JK_AJP_STATE_PROBE;
     if (busy > aw->s->max_busy)
@@ -2995,6 +3011,8 @@ int ajp_init(jk_worker_t *pThis,
                                          JK_SLEEP_DEF);
         p->cache_acquire_timeout = jk_get_worker_cache_acquire_timeout(props,
                                      p->name, p->retries * p->retry_interval);
+        p->busy_limit =
+            jk_get_worker_busy_limit(props, p->name, 0);
         jk_get_worker_fail_on_status(props, p->name,
                                      &(p->http_status_fail),
                                      &(p->http_status_fail_num));
@@ -3066,6 +3084,10 @@ int ajp_init(jk_worker_t *pThis,
             jk_log(l, JK_LOG_DEBUG,
                    "retry interval:         %d",
                     p->retry_interval);
+
+            jk_log(l, JK_LOG_DEBUG,
+                   "busy limit:         %d",
+                    p->busy_limit);
         }
         /*
          *  Need to initialize secret here since we could return from inside

Modified: tomcat/jk/trunk/native/common/jk_ajp_common.h
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.h?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp_common.h (original)
+++ tomcat/jk/trunk/native/common/jk_ajp_common.h Wed Jan  7 16:15:28 2015
@@ -371,6 +371,8 @@ struct ajp_worker
 
     int retry_interval;            /*  Number of milliseconds to sleep before doing a retry */
 
+    int busy_limit;                /*  Maximum allowed number of concurrent requests (if > 0) */
+
     /*
      * HTTP status that will cause failover (0 means disabled)
      */

Modified: tomcat/jk/trunk/native/common/jk_lb_worker.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_lb_worker.c?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_lb_worker.c (original)
+++ tomcat/jk/trunk/native/common/jk_lb_worker.c Wed Jan  7 16:15:28 2015
@@ -50,7 +50,7 @@
  *       activation is none of JK_LB_ACTIVATION_STOPPED, JK_LB_ACTIVATION_DISABLED
  */
 #define JK_WORKER_USABLE(s, activation)   ((s) <= JK_LB_STATE_FORCE && activation == JK_LB_ACTIVATION_ACTIVE)
-#define JK_WORKER_USABLE_STICKY(s, activation)   ((s) <= JK_LB_STATE_BUSY && activation != JK_LB_ACTIVATION_STOPPED)
+#define JK_WORKER_USABLE_STICKY(s, activation)   ((s) <= JK_LB_STATE_FORCE && activation != JK_LB_ACTIVATION_STOPPED)
 
 static const char *lb_locking_type[] = {
     JK_LB_LOCK_TEXT_OPTIMISTIC,
@@ -1213,8 +1213,10 @@ static int JK_METHOD service(jk_endpoint
         jk_lb_pull(p->worker, JK_FALSE, l);
     for (i = 0; i < num_of_workers; i++) {
         lb_sub_worker_t *rec = &(p->worker->lb_workers[i]);
+        ajp_worker_t *aw = (ajp_worker_t *)rec->worker->worker_private;
         if (rec->s->state == JK_LB_STATE_BUSY) {
-            if (ajp_has_endpoint(rec->worker, l)) {
+            if ((aw->busy_limit <= 0 || aw->s->busy < aw->busy_limit) &&
+                ajp_has_endpoint(rec->worker, l)) {
                 if (JK_IS_DEBUG_LEVEL(l))
                     jk_log(l, JK_LOG_DEBUG,
                            "worker %s busy state ended",
@@ -1499,6 +1501,16 @@ static int JK_METHOD service(jk_endpoint
                     rec->s->last_error_time = 0;
                     rc = JK_FALSE;
                 }
+                else if (service_stat == JK_BUSY_ERROR) {
+                    /*
+                     * Node was busy.
+                     * Do not try to reuse the same node for the same request.
+                     * Failing over to another node could help.
+                     */
+                    rec->s->state  = JK_LB_STATE_BUSY;
+                    p->states[rec->i] = JK_LB_STATE_BUSY;
+                    rc = JK_FALSE;
+                }
                 else if (service_stat == JK_STATUS_FATAL_ERROR) {
                     /*
                      * Status code configured as service is down.

Modified: tomcat/jk/trunk/native/common/jk_shm.h
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_shm.h?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_shm.h (original)
+++ tomcat/jk/trunk/native/common/jk_shm.h Wed Jan  7 16:15:28 2015
@@ -91,6 +91,7 @@ struct jk_shm_ajp_worker
     unsigned int recovery_opts;
     int retries;
     int retry_interval;
+    int busy_limit;
     unsigned int max_packet_size;
     /* current error state (runtime) of the worker */
     volatile int state;

Modified: tomcat/jk/trunk/native/common/jk_status.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_status.c?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_status.c (original)
+++ tomcat/jk/trunk/native/common/jk_status.c Wed Jan  7 16:15:28 2015
@@ -135,6 +135,7 @@
 #define JK_STATUS_ARG_AJP_RETRIES          "var"
 #define JK_STATUS_ARG_AJP_RETRY_INT        "vari"
 #define JK_STATUS_ARG_AJP_REC_OPTS         "varo"
+#define JK_STATUS_ARG_AJP_BUSY_LIMIT       "vabl"
 #define JK_STATUS_ARG_AJP_MAX_PK_SZ        "vamps"
 #define JK_STATUS_ARG_AJP_CPING_INT        "vacpi"
 #define JK_STATUS_ARG_AJP_HOST_STR         "vahst"
@@ -148,6 +149,7 @@
 #define JK_STATUS_ARG_AJP_TEXT_RETRIES     "Retries"
 #define JK_STATUS_ARG_AJP_TEXT_RETRY_INT   "Retry Interval"
 #define JK_STATUS_ARG_AJP_TEXT_REC_OPTS    "Recovery Options"
+#define JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT  "Busy Limit"
 #define JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ   "Max Packet Size"
 #define JK_STATUS_ARG_AJP_TEXT_CPING_INT   "Connection Ping Interval"
 #define JK_STATUS_ARG_AJP_TEXT_HOST_STR    "Hostname"
@@ -162,6 +164,7 @@
 #define JK_STATUS_ARG_AJP_HEAD_RETRIES     "Retries"
 #define JK_STATUS_ARG_AJP_HEAD_RETRY_INT   "Retry<br/>Interval"
 #define JK_STATUS_ARG_AJP_HEAD_REC_OPTS    "Recovery<br/>Options"
+#define JK_STATUS_ARG_AJP_HEAD_BUSY_LIMIT  "Busy<br/>Limit"
 #define JK_STATUS_ARG_AJP_HEAD_MAX_PK_SZ   "Max Packet<br/>Size"
 #define JK_STATUS_ARG_AJP_HEAD_CPING_INT   "Connection<br/>Ping Interval"
 #define JK_STATUS_ARG_AJP_HEAD_HOST_STR    "Hostname"
@@ -277,6 +280,7 @@
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_REPLY_TO "</th>" \
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_RETRIES "</th>" \
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_REC_OPTS "</th>" \
+                                           "<th>" JK_STATUS_ARG_AJP_HEAD_BUSY_LIMIT "</th>" \
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_MAX_PK_SZ "</th>" \
                                            "<th>\n"
 #define JK_STATUS_SHOW_AJP_CONF_ROW        "<tr>" \
@@ -288,6 +292,7 @@
                                            "<td>%d</td>" \
                                            "<td>%d</td>" \
                                            "<td>%u</td>" \
+                                           "<td>%d</td>" \
                                            "<td>%u</td>" \
                                            "<td></td>" \
                                            "</tr>\n"
@@ -380,6 +385,7 @@
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_REPLY_TO "</th>" \
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_RETRIES "</th>" \
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_REC_OPTS "</th>" \
+                                           "<th>" JK_STATUS_ARG_AJP_HEAD_BUSY_LIMIT "</th>" \
                                            "<th>" JK_STATUS_ARG_AJP_HEAD_MAX_PK_SZ "</th>" \
                                            "<th>\n"
 #define JK_STATUS_SHOW_MEMBER_CONF_ROW     "<tr>" \
@@ -393,6 +399,7 @@
                                            "<td>%d</td>" \
                                            "<td>%d</td>" \
                                            "<td>%u</td>" \
+                                           "<td>%d</td>" \
                                            "<td>%u</td>" \
                                            "<td></td>" \
                                            "</tr>\n"
@@ -1798,6 +1805,7 @@ static void display_worker_ajp_conf_deta
                   aw->reply_timeout,
                   aw->retries,
                   aw->recovery_opts,
+                  aw->busy_limit,
                   aw->max_packet_size);
     else
         jk_printf(s, l, JK_STATUS_SHOW_AJP_CONF_ROW,
@@ -1810,6 +1818,7 @@ static void display_worker_ajp_conf_deta
                   aw->reply_timeout,
                   aw->retries,
                   aw->recovery_opts,
+                  aw->busy_limit,
                   aw->max_packet_size);
     JK_TRACE_EXIT(l);
 
@@ -1959,6 +1968,7 @@ static void display_worker_ajp_details(j
         jk_print_xml_att_int(s, l, off+2, "connection_ping_interval", aw->conn_ping_interval);
         jk_print_xml_att_int(s, l, off+2, "retries", aw->retries);
         jk_print_xml_att_uint(s, l, off+2, "recovery_options", aw->recovery_opts);
+        jk_print_xml_att_int(s, l, off+2, "busy_limit", aw->busy_limit);
         jk_print_xml_att_uint(s, l, off+2, "max_packet_size", aw->max_packet_size);
         if (lb) {
             jk_print_xml_att_string(s, l, off+2, "activation", jk_lb_get_activation(wr, l));
@@ -2027,6 +2037,7 @@ static void display_worker_ajp_details(j
         jk_printf(s, l, " retries=%d", aw->retries);
         jk_printf(s, l, " connection_ping_interval=%d", aw->conn_ping_interval);
         jk_printf(s, l, " recovery_options=%u", aw->recovery_opts);
+        jk_printf(s, l, " busy_limit=%d", aw->busy_limit);
         jk_printf(s, l, " max_packet_size=%u", aw->max_packet_size);
         if (lb) {
             jk_printf(s, l, " activation=%s", jk_lb_get_activation(wr, l));
@@ -2092,6 +2103,7 @@ static void display_worker_ajp_details(j
         jk_print_prop_att_int(s, l, w, ajp_name, "retries", aw->retries);
         jk_print_prop_att_int(s, l, w, ajp_name, "connection_ping_interval", aw->conn_ping_interval);
         jk_print_prop_att_uint(s, l, w, ajp_name, "recovery_options", aw->recovery_opts);
+        jk_print_prop_att_int(s, l, w, ajp_name, "busy_limit", aw->busy_limit);
         jk_print_prop_att_uint(s, l, w, ajp_name, "max_packet_size", aw->max_packet_size);
         if (lb) {
             jk_print_prop_att_string(s, l, w, ajp_name, "activation", jk_lb_get_activation(wr, l));
@@ -2535,6 +2547,7 @@ static void display_worker_lb(jk_ws_serv
                 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_RETRY_INT, "\">", JK_STATUS_ARG_AJP_TEXT_RETRY_INT, "</option>\n", NULL);
                 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_CPING_INT, "\">", JK_STATUS_ARG_AJP_TEXT_CPING_INT, "</option>\n", NULL);
                 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_REC_OPTS, "\">", JK_STATUS_ARG_AJP_TEXT_REC_OPTS, "</option>\n", NULL);
+                jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_BUSY_LIMIT, "\">", JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT, "</option>\n", NULL);
                 jk_putv(s, "<option value=\"", JK_STATUS_ARG_AJP_MAX_PK_SZ, "\">", JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ, "</option>\n", NULL);
                 jk_puts(s, "</select></td><td><input type=\"submit\" value=\"Go\"/></td></tr></table></form>\n");
             }
@@ -2940,6 +2953,10 @@ static void form_member(jk_ws_service_t
             ":</td><td><input name=\"",
             JK_STATUS_ARG_AJP_REC_OPTS, "\" type=\"text\" ", NULL);
     jk_printf(s, l, "value=\"%d\"/></td></tr>\n", aw->recovery_opts);
+    jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT,
+            ":</td><td><input name=\"",
+            JK_STATUS_ARG_AJP_BUSY_LIMIT, "\" type=\"text\" ", NULL);
+    jk_printf(s, l, "value=\"%d\"/></td></tr>\n", aw->busy_limit);
     jk_putv(s, "<tr><td>", JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ,
             ":</td><td><input name=\"",
             JK_STATUS_ARG_AJP_MAX_PK_SZ, "\" type=\"text\" ", NULL);
@@ -3002,6 +3019,8 @@ static void form_all_members(jk_ws_servi
             aname=JK_STATUS_ARG_AJP_TEXT_CPING_INT;
         else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS))
             aname=JK_STATUS_ARG_AJP_TEXT_REC_OPTS;
+        else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT))
+            aname=JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT;
         else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ))
             aname=JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ;
         else {
@@ -3124,6 +3143,10 @@ static void form_all_members(jk_ws_servi
                 jk_printf(s, l, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
                 jk_printf(s, l, "value=\"%d\"/>\n", aw->recovery_opts);
             }
+            else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT)) {
+                jk_printf(s, l, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
+                jk_printf(s, l, "value=\"%d\"/>\n", aw->busy_limit);
+            }
             else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) {
                 jk_printf(s, l, "<input name=\"" JK_STATUS_ARG_MULT_VALUE_BASE "%d\" type=\"text\"", i);
                 jk_printf(s, l, "value=\"%d\"/>\n", aw->max_packet_size);
@@ -3519,6 +3542,9 @@ static int commit_member(jk_ws_service_t
     if (set_uint_if_changed(p, aw->name, "recovery_options", JK_STATUS_ARG_AJP_REC_OPTS,
                            0, INT_MAX, 1, &aw->recovery_opts, lb_name, l))
         *side_effect |= JK_STATUS_NEEDS_PUSH;
+    if (set_int_if_changed(p, aw->name, "busy_limit", JK_STATUS_ARG_AJP_BUSY_LIMIT,
+                           0, INT_MAX, &aw->busy_limit, lb_name, l))
+        *side_effect |= JK_STATUS_NEEDS_PUSH;
     if (set_uint_if_changed(p, aw->name, "max_packet_size", JK_STATUS_ARG_AJP_MAX_PK_SZ,
                            AJP13_DEF_PACKET_SIZE, AJP13_MAX_PACKET_SIZE, AJP13_PACKET_SIZE_ALIGN,
                            &aw->max_packet_size, lb_name, l)) {
@@ -3585,6 +3611,8 @@ static void commit_all_members(jk_ws_ser
             aname=JK_STATUS_ARG_AJP_TEXT_CPING_INT;
         else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS))
             aname=JK_STATUS_ARG_AJP_TEXT_REC_OPTS;
+        else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT))
+            aname=JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT;
         else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ))
             aname=JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ;
         else {
@@ -3686,6 +3714,11 @@ static void commit_all_members(jk_ws_ser
                                        0, INT_MAX, 1, &aw->recovery_opts, name, l))
                     sync_needed = JK_TRUE;
             }
+            else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT)) {
+                if (set_int_if_changed(p, aw->name, "busy_limit", vname,
+                                       0, INT_MAX, &aw->busy_limit, name, l))
+                    sync_needed = JK_TRUE;
+            }
             else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) {
                 if (set_uint_if_changed(p, aw->name, "max_packet_size", vname,
                                        AJP13_DEF_PACKET_SIZE, AJP13_MAX_PACKET_SIZE, AJP13_PACKET_SIZE_ALIGN,

Modified: tomcat/jk/trunk/native/common/jk_util.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.c?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_util.c (original)
+++ tomcat/jk/trunk/native/common/jk_util.c Wed Jan  7 16:15:28 2015
@@ -92,6 +92,7 @@
 #define WORKER_ERROR_ESCALATION_TIME "error_escalation_time"
 #define MAX_REPLY_TIMEOUTS_OF_WORKER "max_reply_timeouts"
 #define RETRY_INTERVAL_OF_WORKER    "retry_interval"
+#define BUSY_LIMIT_OF_WORKER        "busy_limit"
 #define WORKER_MAX_PACKET_SIZE      "max_packet_size"
 #define STYLE_SHEET_OF_WORKER       "css"
 #define NAMESPACE_OF_WORKER         "ns"
@@ -224,6 +225,7 @@ static const char *unique_properties[] =
     WORKER_ERROR_ESCALATION_TIME,
     MAX_REPLY_TIMEOUTS_OF_WORKER,
     RETRY_INTERVAL_OF_WORKER,
+    BUSY_LIMIT_OF_WORKER,
     WORKER_MAX_PACKET_SIZE,
     STYLE_SHEET_OF_WORKER,
     READ_ONLY_OF_WORKER,
@@ -323,6 +325,7 @@ static const char *supported_properties[
     WORKER_ERROR_ESCALATION_TIME,
     MAX_REPLY_TIMEOUTS_OF_WORKER,
     RETRY_INTERVAL_OF_WORKER,
+    BUSY_LIMIT_OF_WORKER,
     WORKER_MAX_PACKET_SIZE,
     STYLE_SHEET_OF_WORKER,
     NAMESPACE_OF_WORKER,
@@ -1063,6 +1066,19 @@ int jk_get_worker_retry_interval(jk_map_
 
     return jk_map_get_int(m, buf, def);
 }
+
+int jk_get_worker_busy_limit(jk_map_t *m, const char *wname, int def)
+{
+    char buf[PARAM_BUFFER_SIZE];
+
+    if (!m || !wname) {
+        return def;
+    }
+
+    MAKE_WORKER_PARAM(BUSY_LIMIT_OF_WORKER);
+
+    return jk_map_get_int(m, buf, def);
+}
 
 int jk_get_worker_socket_buffer(jk_map_t *m, const char *wname, int def)
 {

Modified: tomcat/jk/trunk/native/common/jk_util.h
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.h?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_util.h (original)
+++ tomcat/jk/trunk/native/common/jk_util.h Wed Jan  7 16:15:28 2015
@@ -109,6 +109,8 @@ int jk_get_worker_max_reply_timeouts(jk_
 
 int jk_get_worker_retry_interval(jk_map_t *m, const char *wname, int def);
 
+int jk_get_worker_busy_limit(jk_map_t *m, const char *wname, int def);
+
 const char *jk_get_worker_route(jk_map_t *m, const char *wname, const char *def);
 
 const char *jk_get_worker_domain(jk_map_t *m, const char *wname, const char *def);

Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original)
+++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Wed Jan  7 16:15:28 2015
@@ -200,6 +200,11 @@
         Status: Use multi-line table headers and fix invalid xml output.
         (rjung)
       </fix>
+      <fix>
+        <bug>44571</bug>: Implement an optional limit on concurrent requests
+        allowed for a worker (attribute "busy_limit"). Original patch
+        contributed by zealot0630 at gmail dot com. (rjung)
+      </fix>
     </changelog>
   </subsection>
 </section>

Modified: tomcat/jk/trunk/xdocs/reference/status.xml
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/reference/status.xml?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/reference/status.xml (original)
+++ tomcat/jk/trunk/xdocs/reference/status.xml Wed Jan  7 16:15:28 2015
@@ -541,6 +541,9 @@ Finally the list of parameters you can u
 <b>varo</b>: recovery_options (number)
 </li>
 <li>
+<b>vabl</b>: busy_limit (number)
+</li>
+<li>
 <b>vamps</b>: max_packet_size (number)
 </li>
 </ul>
@@ -569,7 +572,7 @@ will be triggered by the parameter <b>at
 which aspect you want to edit. The list is the same as in the previous section,
 except for "vahst" and "vaprt":
 "vwa", "vwf", "vwn", "vwr", "vwc", "vwd", "vacpt", "vact", "vapt", "vart", "var",
-"varo" and "vamps". But here you
+"varo", "vabl" and "vamps". But here you
 need to put the name into the parameter <b>att</b>, instead of using it as a request
 parameter name.
 </p>

Modified: tomcat/jk/trunk/xdocs/reference/workers.xml
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/reference/workers.xml?rev=1650098&r1=1650097&r2=1650098&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/reference/workers.xml (original)
+++ tomcat/jk/trunk/xdocs/reference/workers.xml Wed Jan  7 16:15:28 2015
@@ -887,6 +887,18 @@ For example: <code>worker.xxx.fail_on_st
 </p>
 </directive>
 
+<directive name="busy_limit" workers="AJP,SUB" default="0" required="false">
+If set to a positive number, the worker will only be used for a request,
+if it is currently working on less than this number of concurrent requests.
+<p>
+Note that this is not related to the <b>Busyness</b> load balancing
+<b>method</b>.
+</p>
+<p>
+This feature is experimental and has been added in <b>jk 1.2.41</b>.
+</p>
+</directive>
+
 <directive name="max_packet_size" workers="AJP,SUB" default="8192" required="false">
 This attribute sets the maximal AJP packet size in Bytes.
 The maximum value is 65536. If you change it from the default,



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org