4 ms·
It's a lot simpler to just have the socket, with a notification when your PUT has landed. This is what Meteor does. I don't see anything I recognize as eventu
by dgreensp 12y ago
It's a lot simpler to just have the socket, with a notification when your PUT has landed. This is what Meteor does.
I don't see anything I recognize as eventual consistency in the traditional sense. It sounds like the client is just trying to receive a stream of updates, which could have been made by a single writer, and the only consistency issues are caused by the different overlapping mechanisms for getting updates.
- strife25 12y agoThat is certainly simpler. I will say that our notifications come from a different service that is separate from the service the responds to HTTP requests, which leads to the process that is described in my post.
- macspoofing 12y agoThe complexity depends on what constraints you put on yourself. Here's an example, suppose you have a UI panel with a number of checkboxes, radiobuttons, and sliders, and you want to synchronize the state across several users, without blocking (i.e. if a user changes state, he doesn't need to wait for server response to change change state again). Global state exists on a single server. Let's say your users start changing state furiously, what happens? ...well, the object state will live in several places (and slightly different for every client): 1) Local: In the view but before event dispatched to the model. 2) Local: In model but before it was synced to the server. 2a) Local: After model sync and in queue waiting to be sent to the server. 3) Remote: In transit to the server. 4) Remote: On the server (i.e. the one true state). 5) Remote: In transit to the clients. 6) Local: Received but before it was synced to the model. 7) Local: In model but before synced to the view. 8) In the initial state sync (e.g. when a new client joins) So at any given point, every client state is inconsistent with every other client (maybe even significantly if the latency for one or more of the clients is bad) since pieces of the eventual state are spread across all these locations. If now every user stops changing state furiously, every client should eventually be consistent. It's not a hard problem but not completely trivial. For example, you will need conflict resolution rules on the server and in your client and traditional distributed issues like (temporary) network partitioning and latency need to be taken into account. Message ordering will probably matter. >It sounds like the client is just trying to receive a stream of updates, which could have been made by a single writer Not necessarily. You have the same synchronization issues whether the updates are coming from a single source, or from multiple sources.
- dgreensp 12y agoThe EtherPad UI had a bunch of checkboxes and whatnot that were synchronized live, so I definitely acknowledge the problem. We're working on it at Meteor now too. The way I look at it, as long as the server has the final say over the "official" value at any given time -- which seems to be the case here, and is true in all real apps I've seen up to the backend datastore's ability to provide it -- you don't really have a consistency or convergence problem. You just have a UI problem. It's easy for the client to track both the latest official value and what the user is doing, and tell the server about the latter. The only question is what to show the user while their action is still outstanding, and the answer may be different for different kinds of UI. You may want to "fake it till you make it" (Meteor's default, aka latency compensation) or show some kind of loading indicator. What about conflicts? Well, depending on your app, your options for how the server handles operations from the client include: they sometimes fail; they always succeed via "last writer wins" (good for a checkbox, say); they always succeed via operational transforms; or there is application-level conflict resolution that ropes in the user (implemented on top of the foregoing). There's a trend at the moment to view everything as a distributed system, but if you treat a client as a tool for viewing information and calling APIs, it seems a lot simpler.
- josephg 12y agoWe already have this sort of eventual consistency in Derby, built on top of ShareJS. All documents (JSON objects) can be edited synchronously in the browser, and changes are automatically replicated to all other clients. If two people make a change to the same documents at the same time, the changes are merged in a way that will never conflict. For example if we both simultaneously insert into a list embedded in some part of the data model, derby sends a "list insert at position X" operation, which is seamlessly transformed & merged into the document at all sites. The insertion position is updated automatically before merging using the same logic that makes collaborative text editing in etherpad work. Except you can do it over the JSON structures that power your web app.
- macspoofing 12y ago>There's a trend at the moment to view everything as a distributed system, but if you treat a client as a tool for viewing information and calling APIs, it seems a lot simpler. Ok, I guess I must have misunderstood. If you're the guy whose building on-top some synchronization layer, then yeah, it's not really a problem. The sync layer is just another controller that manipulates your model or another consumer of your model changes. If you're the guy implementing the synchronization layer, then you are thinking of distributed systems.
- mcheely 12y agoIt's not always as simple as a PUT landing. Imagine you're tracking something like a phone call in real time. You want to fetch the current state of the call and start tracking it, but it's changing relatively rapidly. You also don't want to have to push the full state of the call down the notification pipe on every update, because you're handling a lot of these. Merging the incoming deltas with fetched API state becomes a bit tricky, because you have to account for changes that might be happening while your GET is in transit. Alternatively, it may be that your notifications are slower than the GET request, depending on network conditions. An option that works in both of these cases (and doesn't involve version tagging all of your assets) is the approach described in the blog post.