Hacker News new | ask | show | jobs
by whilenot-dev 751 days ago
From the article:

> Together, these features enable a web resource to synchronize automatically across multiple clients, servers and proxies, and support arbitrary simultaneous edits by multiple writers, under arbitrary network delays and partitions, while guaranteeing consistency using an OT, CRDT, or other algorithm.

So, you'd use it if you want to "support arbitrary simultaneous edits by multiple writers, under arbitrary network delays and partitions, while guaranteeing consistency", for example for apps that want to support collaborative editing.

Braid wants to turn state transfer (like in RESTful API designs - Representational State Transfer) into a kind of synchronization transfer for state. Currently, state synchronization is handled on the state management layer of each individual application, and API calls just transfer that state, but Braid wants to have it solved as an extension to HTTP libraries on the API layer of an application AFAICS.

1 comments

Yes, or even more simply:

Let's say that your client runs GET /some-json, and that JSON gets updated, and the client wants to get the updates. Right now, your options are:

1. Re-run the GET /some-json again from the client (polling)

2. Start a websocket, and invent some custom protocol over the websocket to let the client subscribe to /some-json.

With Braid, you just do:

    GET /some-json
    Subscribe: true
And the client will automatically get the updates, within HTTP. The Braid-HTTP ponyfill library abstracts the details behind a normal fetch() for you, until browsers implement it.

Today, we tend to use HTTP for static assets, and then switch to a websocket or SSE or something whenever things get dynamic. That sucks! We lose the standard of HTTP!

Braid lets you keep using HTTP, even for your dynamic assets. It also solves issues in caching. Instead of using max-age heuristics, we have actual real versioning!

And yes— the protocol generalizes all the way to full-peer-to-peer multi-writer CRDT/OT algorithms. But start simple!

Frankly, your explanation isn't any simpler, quite the contrary.

> That sucks! We lose the standard of HTTP!

Why does this suck? WebSockets or SSEs are also standardized.

> the protocol generalizes all the way to full-peer-to-peer multi-writer

Why "peer-to-peer"? While Braid can be used in a local-first setting and probably do peer-to-peer, that isn't the focus here.

The focus is to help application developers to not get into the shenanigans of CRDTs and distributed algorithms etc., but solve those things already via polyfills.

> Why "peer-to-peer"? While Braid can be used in a local-first setting and probably do peer-to-peer, that isn't the focus here.

> The focus is to help application developers to not get into the shenanigans of CRDTs and distributed algorithms etc., but solve those things already via polyfills.

Yes, this ^^ is the initial focus, and is enough to provide value now.

However, ultimately we will generalize HTTP into a fully peer-to-peer system. Each extension we add provides a new dimension of p2p, and at some point we won't need servers at all. The big blocker to that, right now, is TLS+DNS, which are baked into the definition of https:// URIs. More on this at https://braid.org/meeting-2 in the "HTTP2P" talk.

Updates (as requested by d-z-m):

- Link to talk in Meeting 2: https://braid.org/video/https://invisiblecollege.s3.us-west-...

- Slides: https://braid.org/files/http2p2p.pdf

- The specific section on TLS+DNS: https://braid.org/video/https://invisiblecollege.s3.us-west-...

In the linked video, is there a timestamp for when the TLS+DNS blocker is discussed?
WebSockets and SSE are standards in the same way that TCP is a standard -- if you use them, you are still defining an ad-hoc protocol on top to subscribe to state and publish new state.

HTTP is a standard on top of TCP. It provides a higher-level abstraction than a socket -- the abstraction of State Transfer. When you use a WebSocket, you're back to a low-level socket, and have to redefine "state", and the methods to get it, put it, and subscribe to it.

Since each web programmer defines those methods in a different way, his state gets hidden behind his own non-standard protocol. There is no way for website A to re-use the state on website B, for instance, without learning website B's custom WebSocket protocol and re-implementing it perfectly.

CDNs and other caches cannot handle WebSocket traffic. But if you use a standard like Braid-HTTP, they can cache your dynamic assets along with your static assets.

Thanks for getting back at me, didn't notice you're the M. Toomim from the article.

I always wanted to tackle CRDTs etc. for state synchronization, but didn't get yet so far. So without much experience in that space, let me ask some really stupid questions...

> HTTP is a standard on top of TCP. It provides a higher-level abstraction than a socket -- the abstraction of State Transfer. When you use a WebSocket, you're back to a low-level socket, and have to redefine "state", and the methods to get it, put it, and subscribe to it.

For an application developer HTTP and WebSocket are both just application traffic protocols. Iv'e seen people misuse the extensibility of HTTP more often than anything WebSocket APIs have to offer. No wonder, state and methods (open, close, send) are much more refined in the WebSocket API standard compared to HTTP - the expectations are low and the responsibility high, libraries handle the basics, don't you think? Why would I go back to the complexity of HTTP again and think about headers and the idempotency of my methods when all I want is to pass payloads to topics in a bidirectional manner? ...I can imagine that CDNs to replay state come into play here, but would need some more inspiration.

> Since each web programmer defines those methods in a different way, their state gets hidden behind their own non-standard protocol. There is no way for website A to re-use the state on website B, for instance, without learning website B's custom WebSocket protocol and re-implementing it perfectly.

What is the use case for an application here? Where there's OpenAPI to document and share REST API implementations, there's AsyncAPI for WebSocket implementations, and of course there's GraphQL and client libraries otherwise... isn't this better approachable with a CollabAPI specification (I just made that up)?

The polyfill design suggests that browsers and standard libraries should implement Braid. What incentive do they have that can't be done with a library?

Yes, the big secret here is that CRDTs + Braid will enable a higher level of abstraction for programmers: an Abstraction of Distributed State.

As a programmer, you'll no longer have to write any networking code. You won't be touching HTTP headers and methods. That will all be handled by libraries for you, which will let you read and write any state, anywhere on the network, as if it's a local variable on your own computer—already downloaded, and always up-to-date.

The CRDT handles network delays, and race conditions, under multiple writers, so that everything merges automatically, and you don't have to think about them.

The Braid Protocol ensures that all servers, everywhere on the network, speak "state sync" in a standard way, even if they have different implementations behind the scenes, even with different algorithms.

This means that our libraries will be able to detect which algorithms need to be employed to synchronize with any service you are connecting to, and implement all that for you. You, as the application programmer, will just read and write variables like:

    state['https://foo.com/news-feed'].push({
       author: 'me',
       post: 'hey guys!!!',
       inreplyto: state['https://bar.net/post/2423h'].id
    })
The reason why HTTP gets abused today is that it doesn't provide full synchronization support, which means that programmers have to abuse it in order to actually write web apps, which becomes a pain in the ass, and then everything feels a lot easier when you drop down into a WebSocket and get rid of the cruft. But now you're writing a custom WebSocket protocol, that only you will fully understand...

...unless you document it, and try to follow a standard like AsyncAPI, which gets you part of the way there...

...but what you really need is a State Synchronization protocol, and libraries that abstract away all the networking for you, and guarantee interoperability, creating a system of shared state. We're getting closer to this glorious world. The magical statebus in the sky that connects all our state together. When the abstraction is complete, it's going to blow everything else away.

We don't need Web Browsers to implement this natively -- that'll just be a performance improvement, like when JSON.stringify() and parse() became native in browsers. The important part is defining a standard that allows us to invest in robust State Sync algorithms and libraries, and lets developers invest in the applications that share this beautifully interoperable state, and make this new abstraction succeed across the globe.