Skip to main content

RemoteFs

Trait RemoteFs 

Source
pub trait RemoteFs {
    // Required methods
    async fn read_batch(&self, paths: &[String]) -> Vec<Result<Vec<u8>>> ;
    async fn read_ranges(&self, reqs: &[RangeReq]) -> Vec<Result<Vec<u8>>> ;
    async fn list_dirs(&self, paths: &[String]) -> Vec<Result<Vec<Entry>>> ;
    async fn home(&self) -> Result<String>;
    async fn append(&self, path: &str, bytes: &[u8]) -> Result<()>;
    async fn mkdirs(&self, path: &str) -> Result<()>;
    fn round_trips(&self) -> u64;

    // Provided method
    async fn list_dir(&self, path: &str) -> Result<Vec<Entry>> { ... }
}

Required Methods§

Source

async fn read_batch(&self, paths: &[String]) -> Vec<Result<Vec<u8>>>

Read whole files. Implementations must issue every request before awaiting any reply; doing otherwise silently reintroduces O(N) round trips.

Source

async fn read_ranges(&self, reqs: &[RangeReq]) -> Vec<Result<Vec<u8>>>

Read byte ranges. Chunking is the implementation’s business; what matters here is that the whole set is issued together, so a one-megabyte range costs one round trip rather than the thirty-two its chunks would suggest.

Source

async fn list_dirs(&self, paths: &[String]) -> Vec<Result<Vec<Entry>>>

List several directories at once. One listing carries every entry’s attrs, which is what removes per-file stat from the page path; batching the listings is what holds a symlink check over a deep path at one round trip rather than one per path component.

Source

async fn home(&self) -> Result<String>

The absolute path a fresh session starts in — the account’s home directory.

The one question about the remote that cannot be answered from a path, and the reason an alias can be written without a base at all. ~ is shell syntax and the transport never runs a shell, so expanding it locally would produce this machine’s home rather than the remote one.

Asked once per alias at startup, never on a page path, so it costs no round trip that a reader waits for.

Source

async fn append(&self, path: &str, bytes: &[u8]) -> Result<()>

Append bytes to a file, creating it if absent.

Append rather than write, and single rather than batched, because that is the only write this design needs and the only one that is safe without a lock. A log has exactly one writer by construction, so an append cannot interleave with anyone else’s — which is precisely why the annotation format is per-author logs and not one shared file.

Source

async fn mkdirs(&self, path: &str) -> Result<()>

Create a directory and every missing parent.

Every level is issued at once and per-level failures are ignored: a level that already exists reports one, and the only outcome that matters is whether the deepest level is there afterwards. Walking down a level per round trip would cost depth round trips for something that happens once per document.

Source

fn round_trips(&self) -> u64

Flushes issued so far. One flush is one remote round trip, so this is the invariant made observable, and assertable in tests.

Provided Methods§

Source

async fn list_dir(&self, path: &str) -> Result<Vec<Entry>>

The n=1 case, defined in terms of the batch so that no implementation can quietly make the single listing the cheap path and the batch a loop.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§