<p>New format code <em>%note</em> to log a transaction annotation linked to the
transaction by ICAP, eCAP, a helper, or the <em>note</em> squid.conf directive.
+ <tag>pipeline_prefetch</tag>
+ <p>Updated to take a numeric count of prefetched pipeline requests instead of ON/OFF.
+
<tag>unlinkd_program</tag>
<p>New helper response format utilizing result codes <em>OK</em> and <em>BH</em>,
to signal helper lookup results. Also, key-value response values to return
#include "squid.h"
#include "cache_cf.h"
#include "compat/strtoll.h"
+#include "ConfigParser.h"
#include "Parsing.h"
#include "globals.h"
#include "Debug.h"
int
GetInteger(void)
{
- char *token = strtok(NULL, w_space);
+ char *token = ConfigParser::strtokFile();
int i;
if (token == NULL)
int ie_refresh;
int vary_ignore_expire;
- int pipeline_prefetch;
int surrogate_is_remote;
int request_entities;
int detect_broken_server_pconns;
int client_dst_passthru;
} onoff;
+ int pipeline_max_prefetch;
+
int forward_max_tries;
int connect_retries;
(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
* 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
#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)
{
onoff
peer
peer_access cache_peer acl
+pipelinePrefetch
PortCfg
QosConfig
refreshpattern
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
}
}
-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;
}
/**
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 */
/**
* 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.
*
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