Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Add APIs for locking files #11511

Closed
dyedgreen opened this issue Jul 24, 2021 · 9 comments · Fixed by #11746
Closed

Feature Request: Add APIs for locking files #11511

dyedgreen opened this issue Jul 24, 2021 · 9 comments · Fixed by #11746
Labels
feat new feature (which has been agreed to/accepted) public API related to "Deno" namespace in JS

Comments

@dyedgreen
Copy link
Contributor

Add sync and async APIs to the Deno namespace which allow to acquire (advisory) file-system locks. The API could look something like this:

interface LockOptions {
  mode: "shared" | "exclusive";
}

interface Deno {
  // ...

  flock: (pid: number, options: LockOptions) => Promise<void>;
  fsyncLock: (pid: number, options: LockOptions) => void;

  funlock: (pid: number) => Promise<void>;
  fsyncUnlock: (pid: number) => void;

  // plus potentially something to check if a file lock can
  // be acquired.
  fcheckLock: (pid: number, options: LockOptions) => Promise<boolean>;
  fsyncCheckLock: (pid: number, options: LockOptions) => boolean;

  // ...
}

One possible good candidate for implementing those on the Rust side would be the fs3 crate.

The motivation for having these APIs is that they would enable synchronization between different processes which access the same file. In particular, this functionality would enable the https://deno.land/x/sqlite library to provide the complete set of persistence guarantees native SQLite offers.

@MierenManz
Copy link

I like the idea alot. and it seems really handy to have.

How would the "shared" and "exclusive" mode work?
Does shared mean that only that deno process + it's workers can lock and unlock the file.
Or does it mean it can share with other pid's like an allow list?

@dyedgreen
Copy link
Contributor Author

dyedgreen commented Jul 24, 2021

Shared mode is like a read only lock, while exclusive mode is like a read-write lock (i.e. multiple shared locks can be held at once, but only one exclusive lock can be held at once).

Note, however, that the locks don't actually prevent you from reading and writing to the file (depending on your OS). This means the processes using the file need to agree to observe the locks to coordinate. (Much like having a struct { data_t data; mutex_t lock_for_data; } in e.g. C)

@kitsonk kitsonk added public API related to "Deno" namespace in JS suggestion suggestions for new features (yet to be agreed) labels Jul 24, 2021
@bartlomieju
Copy link
Member

We should add those APIs, but fs3 crate is unmaintained (last release over a year ago). We need to find some solution that is up to date (I thought such functionality was built into Rust's stdlib, but I might be wrong)

@bartlomieju bartlomieju added feat new feature (which has been agreed to/accepted) and removed suggestion suggestions for new features (yet to be agreed) labels Jul 26, 2021
@MierenManz
Copy link

I couldn't find anything about a file lock system in rust std but I did find this crate https://crates.io/crates/fd-lock
Last update was about a week ago?

@bartlomieju
Copy link
Member

I couldn't find anything about a file lock system in rust std but I did find this crate https://crates.io/crates/fd-lock
Last update was about a week ago?

Yes, this looks good

@MierenManz
Copy link

idk if it is any relevant. But I also found this experimental web api for locking resources https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API
It might be interesting to use as js interface?

@dyedgreen
Copy link
Contributor Author

I think sticking closer to the existing fXXX APIs in the Deno namespace makes more sense. The web locks api is a lot more high level, and would eg not work very well for implementing file locking with SQLite (where a lock needs to be acquired and then passed off to WASM).

I think the web locks api could be built on the more primitive “acquire the lock” and “release the lock” functions and the interface could be included in deno_std/fs.

@axetroy
Copy link
Contributor

axetroy commented Aug 17, 2021

Here are some examples for reference:

Golang implement: https://pkg.go.dev/cmd/go/internal/lockedfile/internal/filelock
vlang implement: https://github.com/vlang/v/pull/11191/files

@dyedgreen
Copy link
Contributor Author

I couldn't find anything about a file lock system in rust std but I did find this crate https://crates.io/crates/fd-lock
Last update was about a week ago?

One concern I have with this crate is that their API (while very nice for the intended usage within a larger rust program) uses RAII guards for the locks, while we probably would want to expose a more low-level API (certainly for use within something like an SQLite VFS).

Having to keep track of locks using a collection of those guard types might be awkward and would probably duplicate some book-keeping the filesystem is doing already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat new feature (which has been agreed to/accepted) public API related to "Deno" namespace in JS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants