Subscribe header

15 views
Skip to first unread message

Duane Johnson

unread,
Jan 26, 2021, 6:27:49 PM1/26/21
to Braid
Synopsis:

Let's brainstorm more accurate/meaningful Subscribe header values. Here's my suggestion:

   Subscribe: this-connection
or Subscribe: retain-on-disconnect=forever
or Subscribe: retain-on-disconnect=<seconds>

Longer Version:

Currently, the Subscribe header does two things:

1. differentiates an HTTP GET request (i.e. a regular non-Braid request) from a Braid subscription request, and
2. describes one of three possible expectations for a Braid subscription after a potential disconnect:

a. "Subscribe"
- as a header on the request, it means "while the connection is open, keep sending me updates to this resource; if the connection closes, the server is not obligated to keep history for me (this client) for any length of time"
- NOTE: this may not be HTTP header compatible, since it does not have a colon and a value

b. "Subscribe: keep-alive"
- as a header on the request, it means: "while the connection is open, keep sending me updates to this resource; even if the connection closes, you (the server) should promise to keep history for me (the client) so that when I reconnect I will still have access to the history as it was when I had been connected"

c. "Subscribe: keep-alive=N [time in seconds]"
- this is like "Subscribe: keep-alive" above, but the client is requesting that the server keep a history for N seconds after any disconnect.

My understanding is that in any of the three expectations above, the server can respond by repeating the Subscribe header (i.e. accepting and making the promise) or by modifying the Subscribe header (i.e. by reducing or eliminating the promise it makes to the client for history retention after disconnect).

I think the meaning of `keep-alive` as currently specified in the Subscription header is slightly misleading:

1. The well-established `Connection:` HTTP 1.1 header (which is also often paired with a "keep-alive" value) "controls whether or not the network connection stays open after the current transaction finishes." So `Connection: keep-alive` means the connection shouldn't be closed, and the "Keep-Alive" header should be heeded. The Subscribe header's "keep-alive" value does not refer to another header (i.e. "Keep-Alive:").

2. The meaning "keep-alive" in "Subscribe: keep-alive" doesn't quite square with "Connection: keep-alive". Braid's "keep-alive" refers to what the server should do with its history after a disconnect, so it isn't really keeping anything "alive" so much as retaining information.

Given the above, I'd like to propose the following:

   Subscribe: this-connection
or Subscribe: retain-on-disconnect=forever
or Subscribe: retain-on-disconnect=<seconds>

Other more accurate and/or short-but-descriptive suggestions are welcome.

Best,
Duane

Seph Gentle

unread,
Jan 31, 2021, 8:30:53 PM1/31/21
to braid...@googlegroups.com
I agree with your instincts here.

For most use cases I can think of, I don't want the server to retain / remember any information about the connecting peer. I want a subscription request to be stateless from the perspective of the server. That is, there should be no persistent state created by the act of subscribing. A subscription should be idempotent.

This matters for scaling. I spent several months figuring out & implementing horizontal scaling for ShareDB. We had a bunch of sharedb instances behind AWS ELB, and we tried to use sticky sessions through AWS to have the same client reconnect to the same server, but it never worked reliably when we redeployed. We ended up moving to a (much better) scaling design where on reconnect the client sent the list of documents which it wanted to subscribe to, and the server (any server) would catch the client up and then send subsequent updates. This is by far my preferred approach - because it works great through load balancers and any sort of scaling. My opinion is that this should be the default, recommended approach.

The other aspect we might want to fit in here somewhere is backpressure. I mentioned in another thread, but if the client falls behind the server (due to insufficient network bandwidth or CPU) the system should behave appropriately. The problem with the current design is the obvious way servers will be written will result in an ever increasing buffer on the server of unsent patches. There's an easy design which fixes this (courtesy of Apache Kafka). And that is, have a subscribe value like:

Subscribe: keep-alive=1m

The semantics here are that the connection will only work for 1m of operations / patches. After that the server will drop the connection, and the client will be expected to resubscribe through a new HTTP request. This way backpressure is impossible - the client won't reconnect until after they've received and processed all the patches in the stream. If that takes a lot of time, thats fine - the server can send whatever content seems appropriate at that time. (Eg, the server could skip sending patches and just send a fresh snapshot to bring the client up to date). I think this is the ideal behaviour that the system could have in the case of slow clients.

But, who decides on the server's connection window? And I think it probably should be the server - in which case, it might make more sense to add this as a header the server returns when the connection is first established.

Thoughts?

-Seph
--
You received this message because you are subscribed to the Google Groups "Braid" group.
To unsubscribe from this group and stop receiving emails from it, send an email to braid-http+...@googlegroups.com.

Duane Johnson

unread,
Feb 1, 2021, 3:23:35 PM2/1/21
to Seph Gentle, Braid
With regard to the meaning of "m" here:

> Subscribe: keep-alive=1m

Is this "1 minute" or "1 million patches"?

Seph Gentle

unread,
Feb 1, 2021, 4:33:02 PM2/1/21
to Duane Johnson, Braid
Oh - 1 megabyte of data. (Or there abouts). 

-Seph

Peter van Hardenberg

unread,
Feb 1, 2021, 4:53:36 PM2/1/21
to Seph Gentle, Duane Johnson, Braid
I agree with the (implied) suggestion for a more explicit unit!



--
Peter van Hardenberg
"Everything was beautiful, and nothing hurt."—Kurt Vonnegut
Reply all
Reply to author
Forward
0 new messages