remotestorage / remotestorage.js

⬡ JavaScript client library for integrating remoteStorage in apps
https://remotestoragejs.readthedocs.io
MIT License
2.32k stars 141 forks source link

problem with localstorage, different clients and save state #108

Closed jancborchardt closed 12 years ago

jancborchardt commented 12 years ago

I use 2–3 different browsers on my computer: Firefox, Chrome and Chromium. Let’s pretend it’s my tablet, my laptop and my smartphone.

I now use Litewrite (dev version) for my own notes and dates, so it’s always open. Now I closed Firefox for a while (didn’t use my tablet) and changed some stuff with Chrome yesterday (my laptop). Then just now I fired up my Firefox (tablet) to check my calendar and jot down some notes, and because the default open document (calendar) looks about similar I just start typing.

Until I realize it’s not the latest version, at which point I panic and think »crap, too late, now it overwrote the version on the server with my just edited thing«. I didn’t think about going offline, check Chrome and rescue that, and I think people shouldn’t have to do that.

How do we solve this problem most comfortably for users? Block until the server is checked – doesn’t work in offline mode and it’s not cool to need to wait to start working. Merge strategies, by lines? Going into versioning is probably a bit too overblown for this basic problem.

We probably talked about this before, and here’s a very basic use case.

nilclass commented 12 years ago

Yes, we talked about this before. @michielbdejong said he was going to add ETags to the spec (an alternative would be to make the Last-Modified header required), I don't think that has happened yet (would need to go to spec version 2012-10, right?). That way each change has a unique tag assigned to it by the server, the server would then refuse PUT requests that don't specify the right tag (meaning that the server has a different version of the data than the one the client last saw). This is similar to the _rev parameter in CouchDB. The client would then see a "409 Conflict" response and have to react to it. remoteStorage.js would probably fire a "conflict" event, then it's up to the app to resolve the conflict (by doing a diff, or by showing both documents to the user, or whatever makes sense and is feasible to handle for both app dev and user).

Until that is added to the spec and implemented by storage providers, we can handle that in remotestoragejs by before each PUT, doing a GET on the parent path (to obtain the timestamp of the resource being updated), then checking if the timestamp matches the timestamp that the client saw before modifying the resource. This introduces a race condition when two clients sync the same paths simultaneously, but is the best we can do without cooperation by the server.

nilclass commented 12 years ago

Conflicts generate an event now. That's all we can do at the moment, so I'm closing this issue.

melvincarvalho commented 12 years ago

On 11 October 2012 16:25, Jan-Christoph Borchardt notifications@github.comwrote:

I use 2–3 different browsers on my computer: Firefox, Chrome and Chromium. Let’s pretend it’s my tablet, my laptop and my smartphone.

I now use Litewrite http://litewrite.github.com/litewrite (dev version) for my own notes and dates, so it’s always open. Now I closed Firefox for a while (didn’t use my tablet) and changed some stuff with Chrome yesterday (my laptop). Then just now I fired up my Firefox (tablet) to check my calendar and jot down some notes, and because the default open document (calendar) looks about similar I just start typing.

Until I realize it’s not the latest version, at which point I panic and think »crap, too late, now it overwrote the version on the server with my just edited thing«. I didn’t think about going offline, check Chrome and rescue that, and I think people shouldn’t have to do that.

How do we solve this problem most comfortably for users? Block until the server is checked – doesn’t work in offline mode and it’s not cool to need to wait to start working. Merge strategies, by lines? Going into versioning is probably a bit too overblown for this basic problem.

We probably talked about this before, and here’s a very basic use case.

This is a good point.

Seems to be that there is basic functionality and extended functionality of syncing remotely.

In the most basic sense remote storage is about PUT and GET, the web equivalents of "load file" and "save file"

There are some extended functionalities tho.

  1. Firstly the per user dimension. So that each user saves to a different place. This essentially has a model component (naming the user) and a controller component (translating that user into a storage location). It may be reasonable to assume that most would want to use this extension, tho there are perhaps some cases when not (e.g. over the wire to a secret location)
  2. Secondly there is the per domain aspect. This is the analogue of localStorage which stores data in different places per subdomain. It could be argued that this extension may not be used by many, however in terms of the naming ie localStrorage / remoteStorage there would be an element of consistency there. This amounts to the same issue again of naming the subdomain, and a function to translate subdomain to storage location.
  3. Device specific. Generally the idea of cloud storage as of today is to sync to all devices. But as Jan points out you can run into issues. Perhaps this could be another extension. It's more difficult to name a device i suspect.
  4. Versioning. Some systems such as couch use versioning to prevent possible conflicts. This is a topic in itself. You need to be careful not to engineer here or you end up with a the kind of fail we saw in Java EJB. I suspect the way to go here is just with 'drivers' for versioning specific targets that are not 100% RESTful.

Seems to me that if the functions are well designed they can be written in a way to be extensible and not conflict with one or extensions that warrant use cases.

— Reply to this email directly or view it on GitHubhttps://github.com/RemoteStorage/remoteStorage.js/issues/108.

nilclass commented 12 years ago

I also added a note to 2012.10 regarding this topic http://www.w3.org/community/unhosted/wiki/RemoteStorage-2012.10#Concurrency_control