4 ms·
It works just fine. Existing servers, proxies, and middleboxes just pass through the response if they don't understand status 209. The braid.org site itself i
by toomim 2y ago
It works just fine. Existing servers, proxies, and middleboxes just pass through the response if they don't understand status 209. The braid.org site itself is running on Braid-HTTP, through a reverse proxy, and everything is peachy keen.
SSE doesn't work because it (1) doesn't support binary data, (2) assumes that versioning is linear (which doesn't work in a distributed system), and doesn't provide any way to add new headers to each response.
SSE also has an awkward encoding format, but that's neither here nor there.
- klabb3 2y ago> doesn't support binary data But HTTP is a text based protocol. Why do you need binary? > assumes that versioning is linear What does linear mean? Afaict SSE ids are opaque strings. > doesn't provide any way to add new headers to each response XY problem? Do you really need HTTP headers or do you need a way to pass X from server to client? I’m not familiar enough with the specific problem, but it’s always good to reuse as much as possible of existing infrastructure.
- __david__ 2y ago> But HTTP is a text based protocol. Why do you say that? It supports binary content just fine. If that were true images would be horribly inefficient to send, like they are with smtp (which is an actual text based protocol).
- remram 2y agoI'm not saying you can reuse the entire SSE protocol and interfaces, but why not use 200 and Content-type text/event-stream, like SSE does? Use mixed/subscription of mixed/braid if you really want, but this whole new thing, why? I don't see what's too fundamentally different about Braid that it needs a new status code and protocol. Shouldn't SSE use 209 then?
- toomim 2y agoIt's possible that Braid could switch back to status code 200. I expect this choice to be revised in discussion within the IETF HTTP WG, but we haven't gotten to this level of detail yet. If I remember correctly, the switch to 209 in the current draft was to discourage middleboxes from caching braid responses, but it's possible that "Cache-Control: no-cache" does enough of this and that 209 is not necessary. I'll keep an eye out. Thanks for the thought. As for text/event-stream -- braid responses are not text (they can contain binary updates to things like images) and they are not an "event" stream. Braid provides an "update" stream, as a stream of HTTP responses. Each response can specify an update using a status code, headers, and a body. If we were to use SSE, we would be encoding an HTTP response, within a base64-encoding (to fit as text), within a sequence of `data: ` lines, in an "event", within an event stream, within a text/event-stream content-type, within an HTTP response. It's a lot simpler to just extend HTTP to say "instead of one response, a server can provide N responses" than to go through all this rigamorale to encode responses within an event stream within a response. As for events vs. updates, an update may or may not describe the raw underlying events. Updates can also be summaries of many events. For instance, a normal HTTP response body provides a snapshot that summarizes all of the edits up to that point that created the resource. This is an update, but is not the raw sequence of events.
- toomim 2y agoAh, I've found the discussion on status code 209 here: https://github.com/braid-org/braid-spec/issues/16 https://github.com/braid-org/braid-spec/issues/16 Hope that helps.
- remram 2y agoUse mixed/braid then. My point is, reuse some of the technical decisions that were made when creating almost the exact same mechanism. What is the point of standard decisions if they change every time?
- bastawhiz 2y ago> doesn't support binary data, You could just as easily base64 encode it (or use your favorite encoding). > assumes that versioning is linear (which doesn't work in a distributed system), Whether you're sending SSE frames or subscription events, they arrive in the order the server sent them by virtue of being sent over TCP. Your versioning is an application-level concern, not a transport-level concern > doesn't provide any way to add new headers to each response. It's trivial to add headers at the application layer (literally just encode your own "header" to the start of each event). The headers don't need to be a part of the protocol.
- toomim 2y agoBase64 encoding hurts performance, adding about 33% overhead. It's more efficient to send binary over HTTP directly. > SSE frames or subscription events ... arrive in the order the server sent them by virtue of being sent over TCP. We support situations more complex than that. Multiple clients can make simultaneous edits with multiple PUTs. They can arrive in different orders to a server that relays them to other clients. Each peer in the system needs to know which versions the edits were parented from, so they can reconstruct the version DAG and merge consistently. > The headers don't need to be a part of the protocol. Yes, they do. Not only headers, but also status lines, and bodies. We are streaming entire HTTP responses. A HTTP response consists of a status line, headers, and a body. We need all of these. For instance, if a resource is deleted, we need to send a new 404 status line in the update. If the version changes, we need to update the Version: header. These need to be a part of the protocol so that all peers can update themselves in the same way, otherwise you don't get consistency.
- bastawhiz 2y ago> Base64 encoding hurts performance, adding about 33% overhead. It's more efficient to send binary over HTTP directly. Other encodings are more space efficient. But it's also the case that the purposes of Braid don't lend themselves to large binary blobs. Chances are the data still fits in a single packet. > They can arrive in different orders to a server that relays them to other clients. Again, whether you emit an update over SSE or a HTTP subscription doesn't change that. Both are literally just TCP connections. Whether you wrap the data as an SSE event or a piece of a 209, it'll arrive in the same way. > Yes, they do. Not only headers, but also status lines, and bodies. We are streaming entire HTTP responses. A HTTP response consists of a status line, headers, and a body. We need all of these. You can package that data not as in the shape of a HTTP response. You're making the choice to do it that way but there's exactly nothing that's requiring you to do it. The value of putting it into HTTP the protocol is making the user agent be able to see a snapshot is a remote resource at any given time. But that's not the interface that HTTP exposes. fetch() or curl gives you back a stream or a buffer. If I created a subscription, streams are right out. So you'd need to get back a full buffer of the resource every time it's updated. But then you don't have data about what changed. So now you have to get the details about those changes, which means HTTP isn't adding any value. Which is to say, if my application needs to be aware of the details of the protocol, it's not a transport protocol anymore, it's an application protocol. If the abstraction of the protocol just gives you ~the data that's sent over the wire, it's not an abstraction anymore and you're really just piping lines of data from the wire to your application logic (which is exactly what SSE is). The only benefit that I can really see is a user agent could facilitate caching better? But then you're dipping into the territory of H2 server push.