Re: [hybi] Extensibility mechanisms?

Jamie Lokier <jamie@shareable.org> Wed, 21 July 2010 00:50 UTC

Return-Path: <jamie@shareable.org>
X-Original-To: hybi@core3.amsl.com
Delivered-To: hybi@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 06F973A69B2 for <hybi@core3.amsl.com>; Tue, 20 Jul 2010 17:50:27 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.67
X-Spam-Level:
X-Spam-Status: No, score=-1.67 tagged_above=-999 required=5 tests=[AWL=0.930, BAYES_00=-2.599]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0CvkD63dNQef for <hybi@core3.amsl.com>; Tue, 20 Jul 2010 17:50:25 -0700 (PDT)
Received: from mail2.shareable.org (mail2.shareable.org [80.68.89.115]) by core3.amsl.com (Postfix) with ESMTP id 5F70B3A6800 for <hybi@ietf.org>; Tue, 20 Jul 2010 17:50:25 -0700 (PDT)
Received: from jamie by mail2.shareable.org with local (Exim 4.63) (envelope-from <jamie@shareable.org>) id 1ObNWA-0007Ly-HR; Wed, 21 Jul 2010 01:50:38 +0100
Date: Wed, 21 Jul 2010 01:50:38 +0100
From: Jamie Lokier <jamie@shareable.org>
To: John Tamplin <jat@google.com>
Message-ID: <20100721005038.GA27243@shareable.org>
References: <4BCB7829.9010204@caucho.com> <Pine.LNX.4.64.1004182349240.751@ps20323.dreamhostps.com> <4BCC0A07.9030003@gmx.de> <Pine.LNX.4.64.1004190753510.23507@ps20323.dreamhostps.com> <4BCC111C.90707@gmx.de> <Pine.LNX.4.64.1004190837570.23507@ps20323.dreamhostps.com> <4BCC204D.30004@gmx.de> <z2gad99d8ce1004190822ne4dd36b6v54d63efcc448e840@mail.gmail.com> <Pine.LNX.4.64.1007202204270.7242@ps20323.dreamhostps.com> <AANLkTimzWAkxG18mgfY_IUtKdsvgv4XLnzKVfsE1aC99@mail.gmail.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <AANLkTimzWAkxG18mgfY_IUtKdsvgv4XLnzKVfsE1aC99@mail.gmail.com>
User-Agent: Mutt/1.5.13 (2006-08-11)
Cc: Hybi <hybi@ietf.org>
Subject: Re: [hybi] Extensibility mechanisms?
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/hybi>
List-Post: <mailto:hybi@ietf.org>
List-Help: <mailto:hybi-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 21 Jul 2010 00:50:27 -0000

John Tamplin wrote:
>    I still don't see the argument for servers written by amateurs. Â I
>    have used far more quick-and-dirty web clients (telnet,
>    socket/connect/write in C, wget/curl, etc) than I have quick-and-dirty
>    servers. Â If some amateur needs to write a server anyway, they aren't
>    going to write it from scratch even if it were possible for them to do
>    so -- they will find some library.
>    Contrast this with embedded clients, which might well have tighter
>    constraints than most clients, and could benefit from having optional
>    features they could leave out that would be useful for more powerful
>    clients. Â Meanwhile, the servers are going to almost certainly be on
>    more powerful machines, though granted they have more connections to
>    support.

But I must say I don't see a problem with keeping it in reach to
amateur programers, at the same time as supporting smarter features.
The two requirements are easily reconciled.

I'm a big fan of the "complex protocols" end of the spectrum - because
I consistently advocate multiplexing, feature negotiation, proxy
opt-ins, message splitting and other "complex" things; all of them are
driven by the desire for good performance (over a variety of
measures), and providing a consistently simple "it just works" API to
the API users.

All that's needed, for amateur programmer compatibility, is for the
"complex" performance-enhancing features to be optional negotiated
features on top of an extremely simple base protocol.  And for the
negotiation to be really simple too.

That's a good idea anyway.

We have a great analogue of this in HTTP's optional persistent
connections.  Simple clients and simple servers don't handle
persistent connections; better ones do, and every combination
works just fine.

Here's how I imagine it working:

The big browsers get decent WS implementations, and are good at
performance-related things that are "hidden under the API", like
automatic sharing of connections, merged keepalives, and maybe even
things like network-signalled-callback on phones.  They request the
most useful enhancers in negotiation, but they work if the answer is
"no".  They can continue to be extended if we think of newer techniques.

Well known servers (Apache etc.) get decent implementations, and can
handle the performance-enhancing features.  They negotiate "yes"
to all the most useful enhancers.

Some proxies like those on a mobile network recognise negotiation and
can add enhancements like network-signalled-callback mentioned above,
and even connection fan-in / fan-out if that proves to be technically
workable.  Other proxies, including HTTP ones, don't participate in
negotiation and are simply transparent.

Joe Random wants to write a quick WebSocket server in half a page of
Python.  That's fine: He implements the minimum base protocol, which
is designed to be very simple (providing the minimum needed for the
WebSocket API to work) and it *just works* with all browsers and other
clients.  Negotiation is basically "no" to all features.

Same when Joe Random wants to write a quick client.

The most important part of this model is that negotiation is sane and
extensible right from the start, and that it has room for all the
interested parties: "below the API" client requested features, proxy
requested/recognised features, server requested features.  The
existing subprotocol field provides the fourth: "above the API" client
requested features.

As setup latency is an issue, it is also important that negotiation
does not incur avoidable round trips.

A second important thing is subtler: It is important that features
negotiated transparently "below the API" are carefully designed to be
*invisible* to WebSocket API users.

Connection sharing is the best example (but it also applies to
keepalive merging): Sending an erroneous message on one channel of a
shared connection must not break all the others; if a receiver event
queue fills, thereby stalling that channel, it must not block messages
from flowing to the others; and sending a very large message on one
channel must not block others for a long time.  Otherwise the
behaviour isn't transparent enough as an *automatic* under-the-hood
replacement for separate connections.

-- Jamie