Re: WGLC: p1 MUST NOT pipeline until connection is persistent

Willy Tarreau <> Wed, 01 May 2013 06:53 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 5D6AD21F86D5 for <>; Tue, 30 Apr 2013 23:53:30 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -10.524
X-Spam-Status: No, score=-10.524 tagged_above=-999 required=5 tests=[AWL=0.075, BAYES_00=-2.599, RCVD_IN_DNSWL_HI=-8]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id cHwELa-zZWki for <>; Tue, 30 Apr 2013 23:53:24 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id 0896A21F867B for <>; Tue, 30 Apr 2013 23:53:23 -0700 (PDT)
Received: from lists by with local (Exim 4.72) (envelope-from <>) id 1UXQuX-0005PZ-QK for; Wed, 01 May 2013 06:53:05 +0000
Resent-Date: Wed, 01 May 2013 06:53:05 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtp (Exim 4.72) (envelope-from <>) id 1UXQuN-0005LX-St for; Wed, 01 May 2013 06:52:55 +0000
Received: from ([]) by with esmtp (Exim 4.72) (envelope-from <>) id 1UXQuM-0008Cn-Qo for; Wed, 01 May 2013 06:52:55 +0000
Received: (from willy@localhost) by mail.home.local (8.14.4/8.14.4/Submit) id r416qQHD028857; Wed, 1 May 2013 08:52:26 +0200
Date: Wed, 1 May 2013 08:52:26 +0200
From: Willy Tarreau <>
To: Alex Rousskov <>
Message-ID: <>
References: <> <> <> <>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <>
User-Agent: Mutt/
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-4.3
X-W3C-Hub-Spam-Report: AWL=-1.792, RP_MATCHES_RCVD=-2.509, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001
X-W3C-Scan-Sig: 1UXQuM-0008Cn-Qo 138df3fe4c367a648643ab38d44addab
Subject: Re: WGLC: p1 MUST NOT pipeline until connection is persistent
Archived-At: <>
X-Mailing-List: <> archive/latest/17748
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

On Tue, Apr 30, 2013 at 05:22:39PM -0600, Alex Rousskov wrote:
> On 04/30/2013 01:40 PM, Willy Tarreau wrote:
> >>> A client [...] MUST NOT pipeline on a retry connection until it
> >>> knows the connection is persistent.
> >> Is it really possible to know that a connection _is_ persistent?
> > Well, it's by definition until a "connection: close" response is seen.
> You are right. My complains about not being able to know whether a
> connection is persistent were invalid because the rules in "p1 6.3
> Persistence" determine whether the connection is considered persistent.
> However, there are two related problems with those rules:
> a) They do not apply to connections on which no responses have been
> received.

I think that it was the reason why it's suggested somewhere that pipelining
should only be done on connections that we know are persistent (ie after a
first response), but that defeats a bit the usefulness of pipelining. Some
clients might probably cache information about what server supports it though.

> b) They do not mention that a persistent connection may close without
> warning at any time.

I'm almost sure it's mentionned somewhere, in the part detailing how to
perform retries.

> Let's start with (a): To know that a connection "is persistent", the
> client has to receive a response on that connection. This implies that
> the client MUST NOT retry a failed pipelined request on a connection it
> just opened.

I don't understand the goal of adding this. If every component in the
chain works correctly, you don't even need to know if the connection
will be persistent, you connect, flood the link with requests and wait
for responses. If it closes before the last response, you know which
ones need to be retried. The suggestions about persistent connections
are just hints to reduce the risk of breaking connections when some
component in the chain don't work well. But the spec should not make
it normative that there are random implementation bugs everywhere and
as such everyone should refrain from doing optimal things if they
know that in some contexts it's perfectly OK.

For example, if your client is installed on a smartphone sold by an
operator which uses transparent proxies as the first element in the
chain, the vendor can have a 100% confidence that pipelining works
and that all connections will be persistent, so you want the client
to assume that for each connection and send whatever it has on each
of them without waiting for a very long round trip to get the first

> What if there are no other connections and not other
> requests to send, except for the failed one? Is the proxy going to be
> stuck because it is not allowed to use a new connection to retry the
> failed pipeline request?
> To fix this, I think we have to add a rule that declares a freshly
> opened, unused connection "persistent" OR allow retries on such
> connections without declaring them persistent.
> As for (b), depending on the intent of this MIST NOT, it may be useful
> to discourage developers from using connections that were idle for a
> long time for retries because those connections are more likely to fail
> when [re]used.

We don't care about this, since the only way to know if the connection is
usable is to try to use it. You have two possibilities then :
  - send a dummy request (eg: OPTIONS *)
  - send a real request

Since the real request is supposed to be idempotent, you don't need to waste
your time sending the dummy request.

I know some applications which use a single connection which lasts a full
day and which sees from 1 to 100 requests on it a day. The time to set up
this connection can be huge because for some clients it requires manual
intervention (cert on a smart card). In such contexts, when you know
everything is compliant in the chain, you don't want to abort these
connections just because they remained unused for 5 hours :-)