remotestorage / remotestorage.js

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

Ability to atomically ensure file doesn't exist with storeFile #887

Open untitaker opened 9 years ago

untitaker commented 9 years ago

(this is a result of the discussion in https://github.com/remotestorage/remotestorage.js/issues/721)

If I want to create a new file with a random filename, there is no race-free way for me to ensure a file with that name doesn't exist yet. I can retrieve a file listing before calling storeFile, but directly after retrieving that file listing (and before I call storeFile), a synchronization process could create a file with that exact name. In such cases I ensured myself that this file doesn't exist, but since it was created immediately after that check, I loose that file's data when writing to it.

Yes, this is a theoretical problem that is unlikely to happen, but if it does happen, I would like my code to throw an error instead of overwriting user data.

The same problem can be solved more generically by acquiring a lock when doing synchronization, and having user code acquire that lock when they do such a "transaction" on local storage.

raucao commented 9 years ago

Isn't If-Match: * required in the spec?

Edit: the spec seems to only speak of ETAGs in regards to If-Match. Could/should probably be added as a new feature in -06 then.

/cc @michielbdejong @fkooman @galfert

galfert commented 9 years ago

You can use If-None-Match: * to prevent existing files from being overwritten. The server responds with a 412 in that case.

storeObject does that automatically. But I don't know if there is an option for it in storeFile.

raucao commented 9 years ago

Ah, right. Could you check why storeFile doesn't do it?

untitaker commented 9 years ago

My point is that I must be able to specify whether I intend to overwrite a file or not, because anything else leads to races.

On 8 September 2015 12:04:47 CEST, Sebastian Kippe notifications@github.com wrote:

Ah, right. Could you check why storeFile doesn't do it?


Reply to this email directly or view it on GitHub: https://github.com/remotestorage/remotestorage.js/issues/887#issuecomment-138502902

Sent from my phone. Please excuse my brevity.

raucao commented 9 years ago

@galfert So a conflict event is thrown then? How would you then resolve it, i.e. overwrite the file from the reject callback?

untitaker commented 9 years ago

As far as I understand this feature would require locks on the cachinglayer? It's easy to extend storeFile to pass an ifMatch option to put, but only the wireclient supports that.

raucao commented 9 years ago

Not sure a lock would help here, as another client can PUT the same file anytime. So the only way to know for sure is sending If-None-Match: * with the very request that doesn't want to overwrite an existing file.

but only the wireclient supports that

You mean the "only wireclient" as opposed to Dropbox and Google Drive, or something else?

untitaker commented 9 years ago

I suppose the remotestorage wireclient.

What I am worried about are race conditions only occuring on localstorage, not across the wire. Particularly I'm worried about the application operating on local storage while remoteStorage.js is syncing.

Since all localstorage operations go through remotestorage.js, it could acquire and release a lock.

On Sat, Sep 12, 2015 at 05:07:03PM -0700, Sebastian Kippe wrote:

Not sure a lock would help here, as another client can PUT the same file anytime. So the only way to know for sure is sending If-None-Match: * with the very request that doesn't want to overwrite an existing file.

but only the wireclient supports that

You mean the "only wireclient" as opposed to Dropbox and Google Drive, or something else?


Reply to this email directly or view it on GitHub: https://github.com/remotestorage/remotestorage.js/issues/887#issuecomment-139830331

untitaker commented 9 years ago

I'm not really familiar with remoteStorage.js' internals but I think what I said applies either way.

On Sat, Sep 12, 2015 at 05:07:03PM -0700, Sebastian Kippe wrote:

Not sure a lock would help here, as another client can PUT the same file anytime. So the only way to know for sure is sending If-None-Match: * with the very request that doesn't want to overwrite an existing file.

but only the wireclient supports that

You mean the "only wireclient" as opposed to Dropbox and Google Drive, or something else?


Reply to this email directly or view it on GitHub: https://github.com/remotestorage/remotestorage.js/issues/887#issuecomment-139830331

raucao commented 9 years ago

Ah, right, got it. In that case a lock would make sense, of course.