=== modified file 'doc/release-notes/release-3.4.sgml' --- doc/release-notes/release-3.4.sgml 2013-05-14 17:54:30 +0000 +++ doc/release-notes/release-3.4.sgml 2013-05-16 03:38:06 +0000 @@ -179,6 +179,9 @@

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 === modified file 'src/Parsing.cc' --- src/Parsing.cc 2013-05-04 13:14:23 +0000 +++ src/Parsing.cc 2013-05-16 13:55:49 +0000 @@ -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 @@ int GetInteger(void) { - char *token = strtok(NULL, w_space); + char *token = ConfigParser::strtokFile(); int i; if (token == NULL) === modified file 'src/SquidConfig.h' --- src/SquidConfig.h 2013-05-13 03:57:03 +0000 +++ src/SquidConfig.h 2013-05-16 03:21:38 +0000 @@ -332,7 +332,6 @@ 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 @@ int client_dst_passthru; } onoff; + int pipeline_max_prefetch; + int forward_max_tries; int connect_retries; === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2013-05-14 18:36:45 +0000 +++ src/cache_cf.cc 2013-05-22 12:17:28 +0000 @@ -965,6 +965,16 @@ (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 @@ * 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 @@ #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) { === modified file 'src/cf.data.depend' --- src/cf.data.depend 2013-05-12 05:04:14 +0000 +++ src/cf.data.depend 2013-05-16 04:00:13 +0000 @@ -51,6 +51,7 @@ onoff peer peer_access cache_peer acl +pipelinePrefetch PortCfg QosConfig refreshpattern === modified file 'src/cf.data.pre' --- src/cf.data.pre 2013-05-14 17:53:18 +0000 +++ src/cf.data.pre 2013-05-21 02:50:03 +0000 @@ -8701,17 +8701,23 @@ 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 === modified file 'src/client_side.cc' --- src/client_side.cc 2013-05-23 08:18:09 +0000 +++ src/client_side.cc 2013-05-25 06:58:00 +0000 @@ -2946,17 +2946,23 @@ } } -static int -connOkToAddRequest(ConnStateData * conn) +bool +ConnStateData::concurrentRequestQueueFilled() const { - int result = conn->getConcurrentRequestCount() < (Config.onoff.pipeline_prefetch ? 2 : 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"); + 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; + + // when queue filled already we cant add more. + if (existingRequestCount >= concurrentRequestLimit) { + debugs(33, 3, clientConnection << " max concurrent requests reached (" << concurrentRequestLimit << ")"); + debugs(33, 5, clientConnection << " defering new request until one is done"); + return false; } - return result; + return true; } /** @@ -2981,8 +2987,8 @@ if (in.notYetUsed == 0) break; - /* Limit the number of concurrent requests to 2 */ - if (!connOkToAddRequest(this)) { + /* Limit the number of concurrent requests */ + if (!pipelineQueueFilled()) { break; } === modified file 'src/client_side.h' --- src/client_side.h 2013-04-04 06:15:00 +0000 +++ src/client_side.h 2013-05-25 07:06:30 +0000 @@ -178,7 +178,7 @@ /** * 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 @@ 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