Hacker News new | comments | show | ask | jobs | submit login
How to design a multi-user ajax web application to be concurrently safe (stackoverflow.com)
80 points by mrleinad on July 7, 2013 | hide | past | web | favorite | 12 comments

A bunch of research was done on this kind of problem in the 1990s under the heading "Operational Transformation".[1] Google have subsequently applied it to Wave and Google Docs.

If you are prepared to accept some suckiness, you can probably do something simpler, borrowing partly from synchronous lockstep RTS simulations.

Put a single canonical model on your server. The server accepts command objects from clients, then forwards them to other clients. If each client is running the same code and applies the same command objects[2] in the same order, they will have identical local models.

It'll drift, of course. Periodically you need to do some sort of checksum and repair. But it's probably simpler than a fully-dressed OT system.

In terms of implementation, I'm working towards this sort of a system currently for an app I am trying to write. AngularJS on the front end, emitting command objects to a server which rebroadcasts to other clients. I don't have the details nailed down. For example, I don't have a firm concept of how or whether to try and coalesce multiple changes locally. And I don't have a firm view on the server system.

[1] http://en.wikipedia.org/wiki/Operational_transformation

[2] http://en.wikipedia.org/wiki/Command_pattern

[3] http://www.altdevblogaday.com/2011/07/09/synchronous-rts-eng...

In some hyp. CMS, I considered just using a token, since the users just edit the same entity only occasionaly.

The first one would hold the token (be able to edit the entity), and the other ones would just see and if they wanted, request a token to edit.

Much simpler than OT/merging/etc, I thought... I wonder if it would work well.

However, in this situation, it's better to ask for forgiveness than permission.

I don't get how this applies here. "Asking for permission" simplifies the system, in this description. Of course, if the conflict rate gets too high, a token-based system fails.

Very thorough answer but I am think there are a lot of scenarios where you don't need every aspect of this solution. I think unique ids and message ordering can handle many cases although not the scenario in the answer. Not sure if someone mentioned but operational transforms might also apply.

Besides OT, check out CRDT.


I don't understand the question. How is using ajax any different than a non-ajax architecture? Doesn't this all boil down to "use optimistic locking" ?

The answer is there is no good answer, at least technically. The best solutions lie in UX, where a user is alerted to the conflict and decides which copy to keep.

One way to do this is:

- have a way of working out which users can see which objects

- whenever an object changes, note that all observers need to see an update

- either push that notification to the user, or record it ready for the next time they poll

- when a user sees "object X has been updated", have them poll for it's latest state (which may be "deleted").

Possible optimisation: you can decorate some or all the "X has changed" messages with the details of the change, creating a journal

This assumes the server can act as a serialisation point for all updates and so provide a single coherent time-series.

It also requires that the server be able to fail updates which are the result of stale UI data. (e.g. someone tries to edit an object someone else has deleted).

I've been pondering this recently and have come to the following conclusions:

* State is expressed as a fold on a stream of events. The Event Sourcing pattern.

* Clients send commands and receive updates to the state on separate channels. (CQRS)

* Sharejs seems to be about the only thing that makes sense to manage client states.

I'd quite like to build the server in Haskell as it's such a good fit for expressing folds over streams.

One thing that I've not really got a handle on though is the correspondence between OT and Event sourcing... Is OT simply the operation that you use to fold the stream of events into a state or is there more to it than that? Enlightenment gratefully received!


Why not look at ShareJS (http://sharejs.org/) and DerbyJS (http://derbyjs.com/)?

Cheers, Victor

There's also MeteorJS (http://meteor.com/) and others...

For the most part combining pub-sub (Redis or others) with a comet/websocket solution (socket.io, SignalR, etc) and and data entities (backbone, angular) that can be used with such a backend (observer) pattern isn't too difficult with the tools available.

Unfortunately there are a lot of options for each part of this, and getting a "right" solution is hard.. there are the auto-magical solutions like you mention, just the same... years of .Net dev make me leary of "magic". I prefer using the most mature/maturing parts and building something useful, like legos.

Applications are open for YC Summer 2018

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact