Subject: Re: [hybi] WS is not a request-response protocol (which would make things easier)

From: "Bob Gezelter" <[email-masked]>
Date: Mon, 15 Aug 2011 12:58:36 -0700

I?aki,

With all due respect, I must disagree. IMHO, "request-response" is not
an appropriate design choice for the WebSocket protocol.

Request-response would effectively make the WebSocket protocol
half-duplex, with the attendant resource utilization and inherent
latency problems, particularly on non-local connections. Additionally,
since the WebSocket protocol is defined to be layered above an
(essentially) error-free, sequence assured transport, the normal reasons
for request-response are not present.

What is likely needed, particularly in a multiplexed context, is a flow
control scheme to avoid clogging the underlying channel. However, that
mechanism, which is generally described as "credit/debit" is far more
amenable to full-duplex, non-blocked operation than "request-response".

- Bob Gezelter, http://www.rlgsc.com

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Mon, 15 Aug 2011 22:09:15 +0200

2011/8/15 Bob Gezelter <[email-masked]>:
> latency problems, particularly on non-local connections.

Hi, why latency? I¡m speaking about very small response (just an id
and status field). Also, I'm not mandating that a second request
requires confirmation (response) of a previous request. Varios
requests can be sent in parallel without waiting for each request's
reponse.

> amenable to full-duplex, non-blocked operation than "request-response".

What about the "id" field I suggest for achieving it?

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Tobias Oberstein <[email-masked]>
Date: Mon, 15 Aug 2011 13:39:37 -0700

> an appropriate design choice for the WebSocket protocol.

couldn't agree more.

> amenable to full-duplex, non-blocked operation than "request-response".

aren't there 2 things involved?

1. access to link (underlying channel) must be fair .. the clogging issue ..
frames must be small enough to do that

2. there should be flow-control between both ends of a logical channel ..
the credit stuff

if you agree, what is appropriate terms to distinguish those 2?

i.e. congestion control vs flow control?

---

From: Stephen Williams <[email-masked]>
Date: Mon, 15 Aug 2011 16:38:18 -0700

> half-duplex, with the attendant resource utilization and inherent

I don't believe that anyone intended "request-response" here to mean half-duplex RPC-style communication.  We've had far too much of 
that for too long and hopefully everyone sees the errors there.  You can still track messages sent in an async, pipelined, message 
oriented fashion to know how much is in the pipeline and when something gets processed.

> for request-response are not present.

That is only true for a 1 tier, client-server application use.  As soon as you have N-tier, you have the case where a message may be 
received by an intermediary but lost before reaching the endpoint.  There are two real solutions: enforce true fire and forget 
semantics which require strong transactional persistence in the face of restarts, etc., and end to end notification of some kind.  
The former generally is expensive in various ways and often results in synchronous or semi-synchronous operation.  The latter 
supports lightweight, message oriented operation and allows the endpoints to understand and manage what's going on.

Any bulk transport of data through an N-tier message oriented system requires end to end flow control and success signalling.  
Anything else will have chronic problems with performance and/or resource overrun (out of memory, etc.).  Something RabbitMQ for 
Wall Street messaging is fine when all of the messages are tiny and the bandwidth is huge.  It's normal modes of usage are 
completely wrong for bulk transfer over congested pipes.

> amenable to full-duplex, non-blocked operation than "request-response".

There are various names for credit/debit, rate-based protocols, end-to-end flow control, etc.  They, in effect, result in some type 
of response to the sender similar to, but sometimes better than, TCP success feedback.  Note that you don't need anything 
synchronous (up to the point where you have exhausted your credit / maximum data in flight), or an ack for each message, or anything 
expensive.  You can piggyback, combine, etc. in a tunable way.  My favorite method is to have each sender explicitly request an ack 
when desired as part of the protocol stream.  This gives maximum flexibility and allows changing parameters and overhead on the fly.

Note that while it may be advantageous to build this capability into the protocol, given certain constraints it is also possible to 
layer it by convention.  For instance, if message order is guaranteed, then you can send small "ack request" messages periodically 
between other messages.  The semantics could be to send back nack on any error or just simply to ack, perhaps with message count or 
serial #s.  This could be one way to handle detection of "message too big to be processed": If an ack of a sentinal before a big 
message is received, and one after that indicates that the big message was skipped or reports actual intervening error codes, then 
you could deduce that the message was too big.

Unless messages are very small already, I think that a per-message ID is not a bad idea, perhaps differentially encoded 
(my.app.stream1.45, .46, .47).
Having a unique ID in email messages is extremely useful.  Here, perhaps a unique connection / stream ID, channel, message ID would 
be useful, at least in debug mode.  Data bloat is the biggest argument against this, but it would be noise in a typical web app 
protocol these days.

> - Bob Gezelter, http://www.rlgsc.com

sdw
-- 
Stephen D. Williams [email-masked] [email-masked] LinkedIn: http://sdw.st/in V:650-450-UNIX (8649) V:866.SDW.UNIX 
V:703.371.9362 F:703.995.0407 AIM:sdw Skype:StephenDWilliams Yahoo:sdwlignet Resume: http://sdw.st/gres Personal: http://sdw.st 
facebook.com/sdwlig twitter.com/scienteer