remotestorage.js icon indicating copy to clipboard operation
remotestorage.js copied to clipboard

Ability to atomically ensure file doesn't exist with storeFile

Open untitaker opened this issue 8 years ago • 10 comments

(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.

untitaker avatar Sep 07 '15 23:09 untitaker

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

raucao avatar Sep 08 '15 09:09 raucao

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.

galfert avatar Sep 08 '15 09:09 galfert

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

raucao avatar Sep 08 '15 10:09 raucao

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 [email protected] 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.

untitaker avatar Sep 08 '15 11:09 untitaker

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

raucao avatar Sep 09 '15 09:09 raucao

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.

untitaker avatar Sep 13 '15 00:09 untitaker

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?

raucao avatar Sep 13 '15 00:09 raucao

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 avatar Sep 13 '15 00:09 untitaker

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

untitaker avatar Sep 13 '15 00:09 untitaker

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

raucao avatar Sep 13 '15 00:09 raucao