]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Make helper queue size configurable, with consistent defaults and better overflow...
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Sun, 9 Nov 2014 21:21:15 +0000 (23:21 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Sun, 9 Nov 2014 21:21:15 +0000 (23:21 +0200)
This patch adds a queue-size=N option to helpers configuration. This
option allows users to configure the maximum number of queued requests
to busy helpers. We also adjusted the default queue size limits to be
more consistent across all helpers and made Squid more robust on some
queue overflows:

- external_acl helpers
    Make the maximum queue size configurable via queue-size.
    Default to 2*maximum-number-of-children.
    If the queue overflows, then the ACL returns ACCESS_DUNNO.

    Unpatched code uses the number of running children as the maximum
    queue size. If the queue is overloaded, then the ACL returns ACCESS_DUNNO.

-redirector/storeID helpers
    Make the maximum queue size configurable via queue-size.
    Default to 2*maximum-number-of-children.
    If the queue overflows and redirector_bypass configuration option
    is set, then redirector is bypassed. Otherwise, if overloading
    persists for more than 3 minutes squid quits with a FATAL message.
    If the redirector_bypass/storeID_bypass is set then the default queue_size
    is set to 0 for backward compatibility.

    Unpatched code uses 2*number-of-running-children as the maximum queue size.
    If the redirector_bypass/storeID_bypass is set then helper bypassed if all
    of the children are busy.
    If the queue is overloaded and redirector_bypass/storeID_bypass is not set
    then squid quits with a FATAL message.

- ssl_crtd/ssl_crtd_validator helpers.
    Make the maximum queue size configurable via queue-size.
    Default to 2*maximum-number-of-children.
    If the queue overflows, then helpers are bypassed. If overloading persists
    for more than 3 minutes squid quits with a FATAL message.

    The default size limit and overflow behavior has not changed.

- Authentication helpers
    Make the maximum queue size configurable via queue-size.
    Default to 2*maximum-number-of-children.
    If the queue overflows and overloading persists for more than 3 minutes,
    then squid quits with a FATAL message.

    The default size limit and overflow behavior has not changed.

This is a Measurement Factory project

doc/release-notes/release-3.6.html
doc/release-notes/release-3.6.sgml
src/cf.data.pre
src/external_acl.cc
src/helper.cc
src/helper.h
src/helper/ChildConfig.cc
src/helper/ChildConfig.h
src/redirect.cc
src/ssl/helper.cc

index d140145d81099c3b58c52eb07f95b97588a05421..96be0194a1f0b60f97058997b7e9b0cbe12728dc 100644 (file)
@@ -24,7 +24,7 @@ for Applied Network Research and members of the Web Caching community.</EM>
 <H2><A NAME="toc2">2.</A> <A HREF="#s2">Major new features since Squid-3.5</A></H2>
 
 <UL>
-<LI><A NAME="toc2.1">2.1</A> <A HREF="#ss2.1">BLAH</A>
+<LI><A NAME="toc2.1">2.1</A> <A HREF="#ss2.1">Configurable helper queue size</A>
 </UL>
 <P>
 <H2><A NAME="toc3">3.</A> <A HREF="#s3">Changes to squid.conf since Squid-3.5</A></H2>
@@ -91,12 +91,11 @@ for how to submit a report with a stack trace.</P>
 <P>Most user-facing changes are reflected in squid.conf (see below).</P>
 
 
-<H2><A NAME="ss2.1">2.1</A> <A HREF="#toc2.1">BLAH</A>
+<H2><A NAME="ss2.1">2.1</A> <A HREF="#toc2.1">Configurable helper queue size</A>
 </H2>
 
-<P>Details at 
-<A HREF="http://wiki.squid-cache.org/Features/BLAH">http://wiki.squid-cache.org/Features/BLAH</A>.</P>
-
+<P>The new queue-size=N option to helpers configuration, allows users 
+to configure the maximum number of queued requests to busy helpers.</P>
 
 <H2><A NAME="s3">3.</A> <A HREF="#toc3">Changes to squid.conf since Squid-3.5</A></H2>
 
@@ -128,7 +127,29 @@ for how to submit a report with a stack trace.</P>
 
 <P>
 <DL>
+<DT><B> auth_param </B><DD>
+<P> New parameter <EM>queue-size=</EM> to set the maximum number
+of queued requests.</P>
+
+<DT><B>external_acl_type</B><DD>
+
+<DT><B></B><DD>
+<P> New parameter <EM>queue-size=</EM> to set the maximum number
+of queued requests.</P>
+
+<DT><B>url_rewrite_children</B><DD>
+
+<DT><B></B><DD>
+<P> New parameter <EM>queue-size=</EM> to set the maximum number
+of queued requests.</P>
+
+<DT><B>sslcrtd_children</B><DD>
+<P> New parameter <EM>queue-size=</EM> to set the maximum number
+of queued requests.</P>
 
+<DT><B>sslcrtvalidator_children</B><DD>
+<P> New parameter <EM>queue-size=</EM> to set the maximum number
+of queued requests.</P>
 </DL>
 </P>
 
index ba62613b98f1bf221dbe479898a4f4fdfeb2dba4..dd36c54b1980098beb857dbc6b01d4db09659b9a 100644 (file)
@@ -44,9 +44,9 @@ The 3.6 change history can be <url url="http://www.squid-cache.org/Versions/v3/3
 Most user-facing changes are reflected in squid.conf (see below).
 
 
-<sect1>BLAH
-<p>Details at <url url="http://wiki.squid-cache.org/Features/BLAH">.
-
+<sect1>Configurable helper queue size
+<p>The new queue-size=N option to helpers configuration, allows users 
+to configure the maximum number of queued requests to busy helpers.
 
 <sect>Changes to squid.conf since Squid-3.5
 <p>
@@ -70,7 +70,25 @@ This section gives a thorough account of those changes in three categories:
 <sect1>Changes to existing tags<label id="modifiedtags">
 <p>
 <descrip>
+         <tag> auth_param </tag>
+         <p> New parameter <em>queue-size=</em> to set the maximum number
+             of queued requests.
+
+         <tag>external_acl_type<tag>
+         <p> New parameter <em>queue-size=</em> to set the maximum number
+             of queued requests.
+
+         <tag>url_rewrite_children<tag>
+         <p> New parameter <em>queue-size=</em> to set the maximum number
+             of queued requests.
+
+         <tag>sslcrtd_children</tag>
+         <p> New parameter <em>queue-size=</em> to set the maximum number
+             of queued requests.
 
+         <tag>sslcrtvalidator_children</tag>
+         <p> New parameter <em>queue-size=</em> to set the maximum number
+             of queued requests.
 </descrip>
 
 <sect1>Removed tags<label id="removedtags">
index 2c43f0eb1e7aaa8c7b1dae3c9d499df7c9211112..0bb4e8c528d5ff780b1e5928a5b74562061f0298 100644 (file)
@@ -428,7 +428,7 @@ DOC_START
                For Digest there is no default, this parameter is mandatory.
                For NTLM and Negotiate this parameter is ignored.
 
-       "children" numberofchildren [startup=N] [idle=N] [concurrency=N]
+       "children" numberofchildren [startup=N] [idle=N] [concurrency=N] [queue-size=N]
 
                The maximum number of authenticator processes to spawn. If
                you start too few Squid will have to wait for them to process
@@ -453,6 +453,11 @@ DOC_START
                Concurrency must not be set unless it's known the helper
                supports the input format with channel-ID fields.
 
+               The queue-size= option sets the maximum number of queued
+               requests. If the queued requests exceed queue size for more
+               than 3 minutes then squid aborts its operation.
+               The default value is set to 2*numberofchildren/
+
                NOTE: NTLM and Negotiate schemes do not support concurrency
                        in the Squid code module even though some helpers can.
 
@@ -646,6 +651,10 @@ DOC_START
                        Up to the value of children-max. (default 1)
          concurrency=n concurrency level per process. Only used with helpers
                        capable of processing more than one query at a time.
+         queue-size=N  The queue-size= option sets the maximum number of queued
+                       requests. If the queued requests exceed queue size 
+                       the acl ignored.
+                       The default value is set to 2*children-max.
          cache=n       limit the result cache size, default is 262144.
          grace=n       Percentage remaining of TTL where a refresh of a
                        cached entry should be initiated without needing to
@@ -2805,6 +2814,13 @@ DOC_START
        at all times. When traffic begins to rise above what the existing
        processes can handle this many more will be spawned up to the maximum
        configured. A minimum setting of 1 is required.
+
+               queue-size=N
+
+       Sets the maximum number of queued requests.
+       If the queued requests exceed queue size for more than 3 minutes
+       squid aborts its operation.
+       The default value is set to 2*numberofchildren.
        
        You must have at least one ssl_crtd process.
 DOC_END
@@ -2864,6 +2880,13 @@ DOC_START
        a request ID in front of the request/response. The request
        ID from the request must be echoed back with the response
        to that request.
+
+               queue-size=N
+
+       Sets the maximum number of queued requests.
+       If the queued requests exceed queue size for more than 3 minutes
+       squid aborts its operation.
+       The default value is set to 2*numberofchildren.
        
        You must have at least one ssl_crt_validator process.
 DOC_END
@@ -4869,6 +4892,14 @@ DOC_START
        used to communicate with the helper is modified to include
        an ID in front of the request/response. The ID from the request
        must be echoed back with the response to that request.
+
+               queue-size=N
+
+       Sets the maximum number of queued requests.
+       If the queued requests exceed queue size and redirector_bypass
+       configuration option is set, then redirector is bypassed. Otherwise, if
+       overloading persists squid may abort its operation.
+       The default value is set to 2*numberofchildren.
 DOC_END
 
 NAME: url_rewrite_host_header redirect_rewrites_host_header
@@ -4919,6 +4950,8 @@ DOC_START
        redirectors for access control, and you enable this option,
        users may have access to pages they should not
        be allowed to request.
+       This options sets default queue-size option of the url_rewrite_children
+       to 0.
 DOC_END
 
 NAME: url_rewrite_extras
@@ -5043,6 +5076,14 @@ DOC_START
        used to communicate with the helper is modified to include
        an ID in front of the request/response. The ID from the request
        must be echoed back with the response to that request.
+
+               queue-size=N
+
+       Sets the maximum number of queued requests.
+       If the queued requests exceed queue size and store_id_bypass
+       configuration option is set, then storeID helper is bypassed. Otherwise,
+       if overloading persists squid may abort its operation.
+       The default value is set to 2*numberofchildren.
 DOC_END
 
 NAME: store_id_access storeurl_rewrite_access
@@ -5072,6 +5113,8 @@ DOC_START
        are not critical to your caching system.  If you use
        helpers for critical caching components, and you enable this 
        option, users may not get objects from cache.
+       This options sets default queue-size option of the store_id_children
+       to 0.
 DOC_END
 
 COMMENT_START
index d1114fd4bbcb151077fa756ee4a1e88d2a53c8bc..19eba8140651bc7290cf8c03af252f8b72b30e69 100644 (file)
@@ -268,6 +268,9 @@ parse_externalAclHelper(external_acl ** list)
             a->children.n_idle = atoi(token + 14);
         } else if (strncmp(token, "concurrency=", 12) == 0) {
             a->children.concurrency = atoi(token + 12);
+        } else if (strncmp(token, "queue-size=", 11) == 0) {
+            a->children.queue_size = atoi(token + 11);
+            a->children.defaultQueueSize = false;
         } else if (strncmp(token, "cache=", 6) == 0) {
             a->cache_size = atoi(token + 6);
         } else if (strncmp(token, "grace=", 6) == 0) {
@@ -315,6 +318,9 @@ parse_externalAclHelper(external_acl ** list)
     if (a->negative_ttl == -1)
         a->negative_ttl = a->ttl;
 
+    if (a->children.queue_size < 0)
+        a->children.queue_size = 2 * a->children.n_max;
+
     /* Parse format */
     external_acl_format::Pointer *p = &a->format;
 
@@ -776,7 +782,7 @@ aclMatchExternal(external_acl_data *acl, ACLFilledChecklist *ch)
         if (!entry) {
             debugs(82, 2, HERE << acl->def->name << "(\"" << key << "\") = lookup needed");
 
-            if (acl->def->theHelper->stats.queue_size < (int)acl->def->theHelper->childs.n_active) {
+            if (!acl->def->theHelper->queueFull()) {
                 debugs(82, 2, HERE << "\"" << key << "\": queueing a call.");
                 if (!ch->goAsync(ExternalACLLookup::Instance()))
                     debugs(82, 2, "\"" << key << "\": no async support!");
@@ -1415,16 +1421,6 @@ ExternalACLLookup::Start(ACLChecklist *checklist, external_acl_data *acl, bool i
     } else {
         /* No pending lookup found. Sumbit to helper */
 
-        /* Check for queue overload */
-
-        if (def->theHelper->stats.queue_size >= (int)def->theHelper->childs.n_running) {
-            debugs(82, 7, HERE << "'" << def->name << "' queue is too long");
-            assert(inBackground); // or the caller should have checked
-            cbdataFree(state);
-            return;
-        }
-
-        /* Send it off to the helper */
         MemBuf buf;
         buf.init();
 
@@ -1432,7 +1428,12 @@ ExternalACLLookup::Start(ACLChecklist *checklist, external_acl_data *acl, bool i
 
         debugs(82, 4, "externalAclLookup: looking up for '" << key << "' in '" << def->name << "'.");
 
-        helperSubmit(def->theHelper, buf.buf, externalAclHandleReply, state);
+        if (!def->theHelper->trySubmit(buf.buf, externalAclHandleReply, state)) {
+            debugs(82, 7, HERE << "'" << def->name << "' submit to helper failed");
+            assert(inBackground); // or the caller should have checked
+            cbdataFree(state);
+            return;
+        }
 
         dlinkAdd(state, &state->list, &def->queue);
 
index 96cb72fef49574d91a0d9d6d134683e909ec2d6f..2be10ada3e2f3f85113cd2745cb3f78d4902e8c5 100644 (file)
@@ -374,16 +374,62 @@ helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data)
         callback(data, nilReply);
         return;
     }
+    hlp->prepSubmit();
+    hlp->submit(buf, callback, data);
+}
+
+bool
+helper::queueFull() const {
+    return stats.queue_size > static_cast<int>(childs.queue_size);
+}
+
+/// prepares the helper for request submission via trySubmit() or helperSubmit()
+/// currently maintains full_time and kills Squid if the helper remains full for too long
+void
+helper::prepSubmit()
+{
+    if (!queueFull())
+        full_time = 0;
+    else if (!full_time) // may happen here if reconfigure decreases capacity
+        full_time = squid_curtime;
+    else if (squid_curtime - full_time > 180)
+        fatalf("Too many queued %s requests", id_name);
+}
+
+bool
+helper::trySubmit(const char *buf, HLPCB * callback, void *data)
+{
+    prepSubmit();
 
+    if (queueFull()) {
+        debugs(84, DBG_IMPORTANT, id_name << " drops request due to a full queue");
+        return false; // request was ignored
+    }
+
+    submit(buf, callback, data); // will send or queue
+    return true; // request submitted or queued
+}
+
+/// dispatches or enqueues a helper requests; does not enforce queue limits
+void
+helper::submit(const char *buf, HLPCB * callback, void *data)
+{
     Helper::Request *r = new Helper::Request(callback, data, buf);
     helper_server *srv;
 
-    if ((srv = GetFirstAvailable(hlp)))
+    if ((srv = GetFirstAvailable(this)))
         helperDispatch(srv, r);
     else
-        Enqueue(hlp, r);
+        Enqueue(this, r);
 
     debugs(84, DBG_DATA, Raw("buf", buf, strlen(buf)));
+
+    if (!queueFull()) {
+        full_time = 0;
+    } else if (!full_time) {
+        debugs(84, 3, id_name << " queue became full");
+        full_time = squid_curtime;
+    }
 }
 
 /// lastserver = "server last used as part of a reserved request sequence"
@@ -396,7 +442,12 @@ helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, vo
         callback(data, nilReply);
         return;
     }
+    hlp->prepSubmit();
+    hlp->submit(buf, callback, data, lastserver);
+}
 
+void statefulhelper::submit(const char *buf, HLPCB * callback, void *data, helper_stateful_server * lastserver)
+{
     Helper::Request *r = new Helper::Request(callback, data, buf);
 
     if ((buf != NULL) && lastserver) {
@@ -408,14 +459,21 @@ helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, vo
         helperStatefulDispatch(lastserver, r);
     } else {
         helper_stateful_server *srv;
-        if ((srv = StatefulGetFirstAvailable(hlp))) {
+        if ((srv = StatefulGetFirstAvailable(this))) {
             helperStatefulDispatch(srv, r);
         } else
-            StatefulEnqueue(hlp, r);
+            StatefulEnqueue(this, r);
     }
 
     debugs(84, DBG_DATA, "placeholder: '" << r->placeholder <<
            "', " << Raw("buf", buf, (!buf?0:strlen(buf))));
+
+    if (!queueFull()) {
+        full_time = 0;
+    } else if (!full_time) {
+        debugs(84, 3, id_name << " queue became full");
+        full_time = squid_curtime;
+    }
 }
 
 /**
@@ -1060,6 +1118,7 @@ helperStatefulHandleRead(const Comm::ConnectionPointer &conn, char *buf, size_t
     }
 }
 
+/// Handles a request when all running helpers, if any, are busy.
 static void
 Enqueue(helper * hlp, Helper::Request * r)
 {
@@ -1074,7 +1133,7 @@ Enqueue(helper * hlp, Helper::Request * r)
         return;
     }
 
-    if (hlp->stats.queue_size < (int)hlp->childs.n_running)
+    if (hlp->stats.queue_size < (int)hlp->childs.queue_size)
         return;
 
     if (squid_curtime - hlp->last_queue_warn < 600)
@@ -1088,9 +1147,6 @@ Enqueue(helper * hlp, Helper::Request * r)
     debugs(84, DBG_CRITICAL, "WARNING: All " << hlp->childs.n_active << "/" << hlp->childs.n_max << " " << hlp->id_name << " processes are busy.");
     debugs(84, DBG_CRITICAL, "WARNING: " << hlp->stats.queue_size << " pending requests queued");
     debugs(84, DBG_CRITICAL, "WARNING: Consider increasing the number of " << hlp->id_name << " processes in your config file.");
-
-    if (hlp->stats.queue_size > (int)hlp->childs.n_running * 2)
-        fatalf("Too many queued %s requests", hlp->id_name);
 }
 
 static void
@@ -1107,12 +1163,9 @@ StatefulEnqueue(statefulhelper * hlp, Helper::Request * r)
         return;
     }
 
-    if (hlp->stats.queue_size < (int)hlp->childs.n_running)
+    if (hlp->stats.queue_size < (int)hlp->childs.queue_size)
         return;
 
-    if (hlp->stats.queue_size > (int)hlp->childs.n_running * 2)
-        fatalf("Too many queued %s requests", hlp->id_name);
-
     if (squid_curtime - hlp->last_queue_warn < 600)
         return;
 
index 074f51ebbab703e4a83c00f4264e8dbd130012b0..120370da74eeedcb5c5411513716f9aeccca348b 100644 (file)
 #include "helper/forward.h"
 #include "ip/Address.h"
 
+/**
+ * Managers a set of individual helper processes with a common queue of requests.
+ *
+ * With respect to load, a helper goes through these states (roughly):
+ *   idle:   no processes are working on requests (and no requests are queued);
+ *   normal: some, but not all processes are working (and no requests are queued);
+ *   busy:   all processes are working (and some requests are possibly queued);
+ *   full:   all processes are working and at least 2*#processes requests are queued.
+ *
+ * A "busy" helper queues new requests and issues a WARNING every 10 minutes or so.
+ * A "full" helper either drops new requests or keeps queuing them, depending on
+ *   whether the caller can handle dropped requests (trySubmit vs helperSubmit APIs).
+ * An attempt to use a "full" helper that has been "full" for 3+ minutes kills worker.
+ *   Given enough load, all helpers except for external ACL will make such attempts.
+ */
 class helper
 {
     CBDATA_CLASS(helper);
@@ -29,6 +44,7 @@ public:
             cmdline(NULL),
             id_name(name),
             ipc_type(0),
+            full_time(0),
             last_queue_warn(0),
             last_restart(0),
             eom('\n') {
@@ -36,6 +52,12 @@ public:
     }
     ~helper();
 
+    ///< whether at least one more request can be successfully submitted
+    bool queueFull() const;
+
+    ///< If not full, submit request. Otherwise, either kill Squid or return false.
+    bool trySubmit(const char *buf, HLPCB * callback, void *data);
+
 public:
     wordlist *cmdline;
     dlink_list servers;
@@ -44,6 +66,7 @@ public:
     Helper::ChildConfig childs;    ///< Configuration settings for number running.
     int ipc_type;
     Ip::Address addr;
+    time_t full_time; ///< when a full helper became full (zero for non-full helpers)
     time_t last_queue_warn;
     time_t last_restart;
     char eom;   ///< The char which marks the end of (response) message, normally '\n'
@@ -54,6 +77,11 @@ public:
         int queue_size;
         int avg_svc_time;
     } stats;
+
+protected:
+    friend void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data);
+    void prepSubmit();
+    void submit(const char *buf, HLPCB * callback, void *data);
 };
 
 class statefulhelper : public helper
@@ -68,6 +96,10 @@ public:
     MemAllocator *datapool;
     HLPSAVAIL *IsAvailable;
     HLPSONEQ *OnEmptyQueue;
+
+private:
+    friend void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPCB * callback, void *data, helper_stateful_server * lastserver);
+    void submit(const char *buf, HLPCB * callback, void *data, helper_stateful_server *lastserver);
 };
 
 /**
index 0d84a99f47da90feff6e4a82fb150debe62077c0..f628025dbce0932d605fe72d49afd9dc06c392f9 100644 (file)
@@ -22,7 +22,9 @@ Helper::ChildConfig::ChildConfig():
         n_idle(1),
         concurrency(0),
         n_running(0),
-        n_active(0)
+        n_active(0),
+        queue_size(0),
+        defaultQueueSize(true)
 {}
 
 Helper::ChildConfig::ChildConfig(const unsigned int m):
@@ -31,7 +33,9 @@ Helper::ChildConfig::ChildConfig(const unsigned int m):
         n_idle(1),
         concurrency(0),
         n_running(0),
-        n_active(0)
+        n_active(0),
+        queue_size(2 * m),
+        defaultQueueSize(true)
 {}
 
 Helper::ChildConfig &
@@ -43,6 +47,8 @@ Helper::ChildConfig::updateLimits(const Helper::ChildConfig &rhs)
     n_startup = rhs.n_startup;
     n_idle = rhs.n_idle;
     concurrency = rhs.concurrency;
+    queue_size = rhs.queue_size;
+    defaultQueueSize = rhs.defaultQueueSize;
     return *this;
 }
 
@@ -87,6 +93,9 @@ Helper::ChildConfig::parseConfig()
             }
         } else if (strncmp(token, "concurrency=", 12) == 0) {
             concurrency = xatoui(token + 12);
+        } else if (strncmp(token, "queue-size=", 11) == 0) {
+            queue_size = xatoui(token + 11);
+            defaultQueueSize = false;
         } else {
             debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Undefined option: " << token << ".");
             self_destruct();
@@ -104,4 +113,7 @@ Helper::ChildConfig::parseConfig()
         debugs(0, DBG_CRITICAL, "WARNING OVERIDE: Capping idle=" << n_idle << " to the defined maximum (" << n_max <<")");
         n_idle = n_max;
     }
+    
+    if (defaultQueueSize)
+        queue_size = 2 * n_max;
 }
index ed09989ef6ae8a28dd7fae4fcb94442ece973a83..a5ed9fa9a241ab6cd3aea108334853919535d81b 100644 (file)
@@ -84,6 +84,18 @@ public:
      * This includes both idle and in-use children.
      */
     unsigned int n_active;
+
+    /**
+     * The requests queue size. By default it is of size 2*n_max
+     */
+    unsigned int queue_size;
+
+    /**
+     * True if the default queue size is used.
+     * Needed in the cases where we need to adjust default queue_size in
+     * special configurations, for example when redirector_bypass is used.
+     */
+    bool defaultQueueSize;
 };
 
 } // namespace Helper
index f13bd7f8f700024bf039b7ced247fd38a62cf386..bcc8860147b9f1a81eb194585c12b13d9ddd770c 100644 (file)
@@ -290,8 +290,8 @@ redirectStart(ClientHttpRequest * http, HLPCB * handler, void *data)
     assert(handler);
     debugs(61, 5, "redirectStart: '" << http->uri << "'");
 
-    if (Config.onoff.redirector_bypass && redirectors->stats.queue_size) {
-        /* Skip redirector if there is one request queued */
+    if (Config.onoff.redirector_bypass && redirectors->queueFull()) {
+        /* Skip redirector if the queue is full */
         ++redirectorBypassed;
         Helper::Reply bypassReply;
         bypassReply.result = Helper::Okay;
@@ -314,8 +314,8 @@ storeIdStart(ClientHttpRequest * http, HLPCB * handler, void *data)
     assert(handler);
     debugs(61, 5, "storeIdStart: '" << http->uri << "'");
 
-    if (Config.onoff.store_id_bypass && storeIds->stats.queue_size) {
-        /* Skip StoreID Helper if there is one request queued */
+    if (Config.onoff.store_id_bypass && storeIds->queueFull()) {
+        /* Skip StoreID Helper if the queue is full */
         ++storeIdBypassed;
         Helper::Reply bypassReply;
 
@@ -346,6 +346,11 @@ redirectInit(void)
 
         redirectors->cmdline = Config.Program.redirect;
 
+        // BACKWARD COMPATIBILITY:
+        // if redirectot_bypass is set then use queue_size=0 as default size
+        if (Config.onoff.redirector_bypass && Config.redirectChildren.defaultQueueSize)
+            Config.redirectChildren.queue_size = 0;
+
         redirectors->childs.updateLimits(Config.redirectChildren);
 
         redirectors->ipc_type = IPC_STREAM;
@@ -360,6 +365,11 @@ redirectInit(void)
 
         storeIds->cmdline = Config.Program.store_id;
 
+        // BACKWARD COMPATIBILITY:
+        // if store_id_bypass is set then use queue_size=0 as default size
+        if (Config.onoff.store_id_bypass && Config.storeIdChildren.defaultQueueSize)
+            Config.storeIdChildren.queue_size = 0;
+
         storeIds->childs.updateLimits(Config.storeIdChildren);
 
         storeIds->ipc_type = IPC_STREAM;
index 23e36955ea71a1c99f12354a8aaba51bdb7cc7f9..81859c353efa4d38666bf6d0bfcf38583723fe71 100644 (file)
@@ -98,26 +98,17 @@ void Ssl::Helper::Shutdown()
 
 void Ssl::Helper::sslSubmit(CrtdMessage const & message, HLPCB * callback, void * data)
 {
-    static time_t first_warn = 0;
     assert(ssl_crtd);
 
-    if (ssl_crtd->stats.queue_size >= (int)(ssl_crtd->childs.n_running * 2)) {
-        if (first_warn == 0)
-            first_warn = squid_curtime;
-        if (squid_curtime - first_warn > 3 * 60)
-            fatal("SSL servers not responding for 3 minutes");
-        debugs(34, DBG_IMPORTANT, HERE << "Queue overload, rejecting");
+    std::string msg = message.compose();
+    msg += '\n';
+    if (!ssl_crtd->trySubmit(msg.c_str(), callback, data)) {
         ::Helper::Reply failReply;
         failReply.result = ::Helper::BrokenHelper;
         failReply.notes.add("message", "error 45 Temporary network problem, please retry later");
         callback(data, failReply);
         return;
     }
-
-    first_warn = 0;
-    std::string msg = message.compose();
-    msg += '\n';
-    helperSubmit(ssl_crtd, msg.c_str(), callback, data);
 }
 #endif //USE_SSL_CRTD
 
@@ -251,22 +242,8 @@ sslCrtvdHandleReplyWrapper(void *data, const ::Helper::Reply &reply)
 
 void Ssl::CertValidationHelper::sslSubmit(Ssl::CertValidationRequest const &request, Ssl::CertValidationHelper::CVHCB * callback, void * data)
 {
-    static time_t first_warn = 0;
     assert(ssl_crt_validator);
 
-    if (ssl_crt_validator->stats.queue_size >= (int)(ssl_crt_validator->childs.n_running * 2)) {
-        if (first_warn == 0)
-            first_warn = squid_curtime;
-        if (squid_curtime - first_warn > 3 * 60)
-            fatal("ssl_crtvd queue being overloaded for long time");
-        debugs(83, DBG_IMPORTANT, "WARNING: ssl_crtvd queue overload, rejecting");
-        Ssl::CertValidationResponse resp;
-        resp.resultCode = ::Helper::BrokenHelper;
-        callback(data, resp);
-        return;
-    }
-    first_warn = 0;
-
     Ssl::CertValidationMsg message(Ssl::CrtdMessage::REQUEST);
     message.setCode(Ssl::CertValidationMsg::code_cert_validate);
     message.composeRequest(request);
@@ -289,5 +266,15 @@ void Ssl::CertValidationHelper::sslSubmit(Ssl::CertValidationRequest const &requ
         delete crtdvdData;
         return;
     }
-    helperSubmit(ssl_crt_validator, crtdvdData->query.c_str(), sslCrtvdHandleReplyWrapper, crtdvdData);
+
+    if (!ssl_crt_validator->trySubmit(crtdvdData->query.c_str(), sslCrtvdHandleReplyWrapper, crtdvdData)) {
+        Ssl::CertValidationResponse resp;
+        resp.resultCode = ::Helper::BrokenHelper;
+        callback(data, resp);
+
+        cbdataReferenceDone(crtdvdData->data);
+        SSL_free(crtdvdData->ssl);
+        delete crtdvdData;
+        return;
+    }
 }