From: Amos Jeffries Date: Sun, 26 May 2013 01:57:47 +0000 (-0600) Subject: Enable length configuration for pipeline_prefetch queue X-Git-Tag: SQUID_3_4_0_1~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=079a84803cb4d685fbe1997dbe4c9259766741d2;p=thirdparty%2Fsquid.git Enable length configuration for pipeline_prefetch queue Updates the queue length magic numbers (2) by making pipeline_prefetch a numeric queus length instead of aon/off toggle. Also, adds configuration file consistency check for pipeline enabled when client prsistent connections disable. --- diff --git a/doc/release-notes/release-3.4.sgml b/doc/release-notes/release-3.4.sgml index 677581501c..2c48e82490 100644 --- a/doc/release-notes/release-3.4.sgml +++ b/doc/release-notes/release-3.4.sgml @@ -179,6 +179,9 @@ This section gives a thorough account of those changes in three categories:

New format code %note to log a transaction annotation linked to the transaction by ICAP, eCAP, a helper, or the note squid.conf directive. + pipeline_prefetch +

Updated to take a numeric count of prefetched pipeline requests instead of ON/OFF. + unlinkd_program

New helper response format utilizing result codes OK and BH, to signal helper lookup results. Also, key-value response values to return diff --git a/src/Parsing.cc b/src/Parsing.cc index 1a764878d9..b180eaa431 100644 --- a/src/Parsing.cc +++ b/src/Parsing.cc @@ -33,6 +33,7 @@ #include "squid.h" #include "cache_cf.h" #include "compat/strtoll.h" +#include "ConfigParser.h" #include "Parsing.h" #include "globals.h" #include "Debug.h" @@ -161,7 +162,7 @@ GetInteger64(void) int GetInteger(void) { - char *token = strtok(NULL, w_space); + char *token = ConfigParser::strtokFile(); int i; if (token == NULL) diff --git a/src/SquidConfig.h b/src/SquidConfig.h index 3d3cfaaf3b..a46a733cad 100644 --- a/src/SquidConfig.h +++ b/src/SquidConfig.h @@ -332,7 +332,6 @@ public: int ie_refresh; int vary_ignore_expire; - int pipeline_prefetch; int surrogate_is_remote; int request_entities; int detect_broken_server_pconns; @@ -361,6 +360,8 @@ public: int client_dst_passthru; } onoff; + int pipeline_max_prefetch; + int forward_max_tries; int connect_retries; diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 265abd09c0..d340169518 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -965,6 +965,16 @@ configDoConfigure(void) (uint32_t)Config.maxRequestBufferSize, (uint32_t)Config.maxRequestHeaderSize); } + /* + * Disable client side request pipelining if client_persistent_connections OFF. + * Waste of resources queueing any pipelined requests when the first will close the connection. + */ + if (Config.pipeline_max_prefetch > 0 && !Config.onoff.client_pconns) { + debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: pipeline_prefetch " << Config.pipeline_max_prefetch << + " requires client_persistent_connections ON. Forced pipeline_prefetch 0."); + Config.pipeline_max_prefetch = 0; + } + #if USE_AUTH /* * disable client side request pipelining. There is a race with @@ -973,12 +983,12 @@ configDoConfigure(void) * pipelining OFF, the client may fail to authenticate, but squid's * state will be preserved. */ - if (Config.onoff.pipeline_prefetch) { + if (Config.pipeline_max_prefetch > 0) { Auth::Config *nego = Auth::Config::Find("Negotiate"); Auth::Config *ntlm = Auth::Config::Find("NTLM"); if ((nego && nego->active()) || (ntlm && ntlm->active())) { - debugs(3, DBG_IMPORTANT, "WARNING: pipeline_prefetch breaks NTLM and Negotiate authentication. Forced OFF."); - Config.onoff.pipeline_prefetch = 0; + debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: pipeline_prefetch breaks NTLM and Negotiate authentication. Forced pipeline_prefetch 0."); + Config.pipeline_max_prefetch = 0; } } #endif @@ -2691,6 +2701,29 @@ parse_tristate(int *var) #define free_tristate free_int +void +parse_pipelinePrefetch(int *var) +{ + char *token = ConfigParser::strtokFile(); + + if (token == NULL) + self_destruct(); + + if (!strcmp(token, "on")) { + debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: 'pipeline_prefetch on' is deprecated. Please update to use 1 (or a higher number)."); + *var = 1; + } else if (!strcmp(token, "off")) { + debugs(0, DBG_PARSE_NOTE(2), "WARNING: 'pipeline_prefetch off' is deprecated. Please update to use '0'."); + *var = 0; + } else { + ConfigParser::strtokFileUndo(); + parse_int(var); + } +} + +#define free_pipelinePrefetch free_int +#define dump_pipelinePrefetch dump_int + static void dump_refreshpattern(StoreEntry * entry, const char *name, RefreshPattern * head) { diff --git a/src/cf.data.depend b/src/cf.data.depend index ece4bf2651..c28b3e7586 100644 --- a/src/cf.data.depend +++ b/src/cf.data.depend @@ -51,6 +51,7 @@ obsolete onoff peer peer_access cache_peer acl +pipelinePrefetch PortCfg QosConfig refreshpattern diff --git a/src/cf.data.pre b/src/cf.data.pre index c4d7626849..c8cb4d13cf 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -8710,17 +8710,23 @@ DOC_START DOC_END NAME: pipeline_prefetch -TYPE: onoff -LOC: Config.onoff.pipeline_prefetch -DEFAULT: off +TYPE: pipelinePrefetch +LOC: Config.pipeline_max_prefetch +DEFAULT: 0 +DEFAULT_DOC: Do not pre-parse pipelined requests. DOC_START - To boost the performance of pipelined requests to closer - match that of a non-proxied environment Squid can try to fetch - up to two requests in parallel from a pipeline. + HTTP clients may send a pipeline of 1+N requests to Squid using a + single connection, without waiting for Squid to respond to the first + of those requests. This option limits the number of concurrent + requests Squid will try to handle in parallel. If set to N, Squid + will try to receive and process up to 1+N requests on the same + connection concurrently. - Defaults to off for bandwidth management and access logging + Defaults to 0 (off) for bandwidth management and access logging reasons. + NOTE: pipelining requires persistent connections to clients. + WARNING: pipelining breaks NTLM and Negotiate/Kerberos authentication. DOC_END diff --git a/src/client_side.cc b/src/client_side.cc index 2b9341a2b5..805eb02fc7 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2946,17 +2946,28 @@ connStripBufferWhitespace (ConnStateData * conn) } } -static int -connOkToAddRequest(ConnStateData * conn) +/** + * Limit the number of concurrent requests. + * \return true when there are available position(s) in the pipeline queue for another request. + * \return false when the pipeline queue is full or disabled. + */ +bool +ConnStateData::concurrentRequestQueueFilled() const { - int result = conn->getConcurrentRequestCount() < (Config.onoff.pipeline_prefetch ? 2 : 1); + const int existingRequestCount = getConcurrentRequestCount(); + + // default to the configured pipeline size. + // add 1 because the head of pipeline is counted in concurrent requests and not prefetch queue + const int concurrentRequestLimit = Config.pipeline_max_prefetch + 1; - if (!result) { - debugs(33, 3, HERE << conn->clientConnection << " max concurrent requests reached"); - debugs(33, 5, HERE << conn->clientConnection << " defering new request until one is done"); + // when queue filled already we cant add more. + if (existingRequestCount >= concurrentRequestLimit) { + debugs(33, 3, clientConnection << " max concurrent requests reached (" << concurrentRequestLimit << ")"); + debugs(33, 5, clientConnection << " deferring new request until one is done"); + return true; } - return result; + return false; } /** @@ -2981,10 +2992,9 @@ ConnStateData::clientParseRequests() if (in.notYetUsed == 0) break; - /* Limit the number of concurrent requests to 2 */ - if (!connOkToAddRequest(this)) { + /* Limit the number of concurrent requests */ + if (concurrentRequestQueueFilled()) break; - } /* Should not be needed anymore */ /* Terminate the string */ diff --git a/src/client_side.h b/src/client_side.h index ffe33e58ce..310de54b8e 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -178,7 +178,7 @@ class ServerBump; /** * Manages a connection to a client. * - * Multiple requests (up to 2) can be pipelined. This object is responsible for managing + * Multiple requests (up to pipeline_prefetch) can be pipelined. This object is responsible for managing * which one is currently being fulfilled and what happens to the queue if the current one * causes the client connection to be closed early. * @@ -392,6 +392,7 @@ private: int connReadWasError(comm_err_t flag, int size, int xerrno); int connFinishedWithConn(int size); void clientAfterReadingRequests(); + bool concurrentRequestQueueFilled() const; #if USE_AUTH /// some user details that can be used to perform authentication on this connection