Skip to main content

FileDatabase

Struct FileDatabase 

Source
pub struct FileDatabase<M: Mode = Writer> { /* private fields */ }
Expand description

File queue and cache access, on the store’s writer or a read-only handle (FileDatabase<ReadOnly>), which reads and caches files and can change only its local cache metadata. The upload and pin queue and the file records are the writer’s. Construct beside the database at the application composition root.

ⓘ
async fn completes_nothing(files: &coven_database::FileDatabase<coven_database::ReadOnly>) {
    files.complete_upload(1, ()).await;
}
ⓘ
fn queues_nothing(files: &coven_database::FileDatabase<coven_database::ReadOnly>) {
    files.queued_work_changes();
}
ⓘ
async fn records_nothing(files: &coven_database::FileDatabase<coven_database::ReadOnly>) {
    files.fail_upload(1, (), None).await;
}

Implementations§

Source§

impl FileDatabase

Source

pub async fn pin_requests(&self) -> Result<Vec<PinRequest>, DbError>

The files a switch to the cloud asked this device to keep whole, each with the copy its cache copy is made from and its wait (§17.8).

Source

pub async fn end_pin_request(&self, id: i64) -> Result<(), DbError>

The file of request id left the stored bytes the request asked to keep: the request, its record and wait end, and the copy it kept goes once nothing else names it.

Source

pub async fn keep( &self, prepared: PreparedPin, id: i64, ) -> Result<bool, DbError>

Make the pin request id asked for from prepared, ending the request in the same write, and return true (§17.8). A request that ended since it was read, by the app’s unpin or the file leaving, makes nothing: false.

Source

pub async fn drop_pin_copy(&self, id: i64) -> Result<(), DbError>

The cache copy couldn’t be made from coven’s copy for request id: the pin downloads from storage instead.

Source

pub async fn fail_pin<P: PendingValue>( &self, request: &PinRequest, record: P, retry: Option<RetryWait>, ) -> Result<(), DbError>

Record a failed attempt at the pin request asked for as its record, with its next wait or none, in one transaction. A request already ended records nothing.

Source

pub async fn copy_chunk_hash( &self, copy: &StagedName, index: u64, ) -> Result<ContentHash, DbError>

The first-read plaintext hash of one chunk of coven’s copy, which the cache copy made from it checks.

Source

pub async fn open_pin_copy( &self, file: &FileRef, copy: &StagedName, ) -> Result<LocalFileStream, LocalFileError>

Open coven’s copy a pin request keeps, which must still have the file’s size; it touches only the disk.

Source§

impl FileDatabase

Source

pub async fn reserve_pin_download( &self, file: &FileRef, fresh: FileName, ) -> Result<(CacheReservation, u64), DbError>

The cache file a prepare of file writes its whole copy to, and how many of its bytes are already kept: the partial copy an earlier prepare left, reserved again, or else fresh, reserved as a new file, with none. The bytes kept are whole chunks after the header, synced.

Source

pub async fn keep_pin_download( &self, reservation: &mut CacheReservation, size: u64, ) -> Result<(), DbError>

Keep the first size bytes of the reservation’s cache file, which are synced, as the partial copy the next prepare continues from. NoLongerStored when no record here names the file’s stored bytes any more, and PinChanged when the app unpinned the file since the copy was reserved, which ended the partial (§17.8).

Source

pub async fn pin_download_kept( &self, file: &FileRef, ) -> Result<Option<(FileName, u64)>, DbError>

The cache file of the partial download kept for file, and how many of its bytes are kept, for a test to look at.

Source

pub async fn discard_pin_download(&self, file: &FileRef) -> Result<(), DbError>

End the partial copy of file, whose bytes are not the file’s: they go once the writer is free.

Source§

impl FileDatabase

Source

pub fn prepared_pin( &self, copies: Vec<CacheReservation>, kept: Vec<FileRef>, ) -> Result<PreparedPin, DbError>

A pin of copies, whole files written, synced and checked, and of kept, files already kept whole. The copies’ names stay reserved until a write commits the pin or it is dropped.

Source

pub async fn commit_pin(&self, prepared: PreparedPin) -> Result<(), DbError>

Commit a prepared pin in a write of its own, as an app’s write does with its pin step, for tests.

Source

pub async fn kept(&self, file: &FileRef) -> Result<bool, DbError>

Whether a checked whole copy of this stored file is kept here, pinned.

Source§

impl FileDatabase

Source

pub async fn device_only_files( &self, files: Vec<FileId>, ) -> Result<Vec<FileRef>, DbError>

Each file as its record stands, once this device may make it device-only (§17.3): in the cloud, of a user namespace, in an audience this device’s member is in, and referenced by no row of an owner_only table another member created. Read in one committed state; the write switching the files checks again.

Source

pub async fn record_copies( &self, copies: Vec<FolderCopy>, ) -> Result<CopyReservation, DbError>

Record the copies one call writes, before any of their folders or bytes exist (Database::record_copies). A path another call is writing a copy at is CopyPathTaken; the returned reservation keeps the copies from other writes’ removals while it is held.

Source

pub async fn made_folder(&self, folder: &Path) -> Result<(), DbError>

The call’s own mkdir made folder: it is the call’s to remove, once empty. A folder that was there already is never marked.

Source

pub async fn place_copy(&self, observed: &ObservedFile) -> Result<(), DbError>

A copy is whole and synced at its path, renamed there from its temporary name, with the size and modification time observed read.

Source

pub fn prepared_device_only( &self, reservation: CopyReservation, copies: Vec<DeviceOnlyCopy>, _flushed: Flushed, ) -> Result<PreparedDeviceOnly, DbError>

The copies a call placed, ready for the write that switches their files to them (§17.3). It takes the flush of the batch the copies were written in: they are on the drive before the commit that records them (Appendix C.3).

Source

pub async fn abandon_copies(&self, paths: Vec<PathBuf>) -> Result<(), DbError>

Remove what a failing call made: the copies at paths it left unswitched, if they are as it left them, and the folders it made for them, if they are empty. A failed removal keeps its record, and the next open removes it.

Source§

impl<M: Mode> FileDatabase<M>

Source

pub fn new(database: Database<M>) -> Self

Use an open store’s handle for its file operations.

Source

pub fn bugs(&self) -> &BugSinkRef

Where a bug in the file owner’s work that nobody waits for goes, as its database’s does (E15).

Source

pub fn records(&self) -> Option<&FileDatabase<Writer>>

The writer’s file owner, which keeps file records and the upload and pin queue; a read-only handle keeps none.

Source

pub async fn file_ref(&self, file: FileId) -> Result<FileRef, DbError>

The file this device has a record of under this id.

Source

pub async fn open_local( &self, file: &FileRef, ) -> Result<Option<LocalFileStream>, LocalFileError>

Open and check the local source of a file still on this device only, while it uploads. None means its bytes come from the cache or storage.

Source

pub async fn cached( &self, file: &FileRef, index: i64, ) -> Result<Option<Vec<u8>>, DbError>

Cached encrypted chunk or header (-1). Its bytes are read with no writer held (§21.2); an entry evicted meanwhile reads as not cached.

Source

pub async fn repair_cached( &self, file: &FileRef, index: i64, bytes: Vec<u8>, ) -> Result<(), DbError>

Write the stored bytes of chunk index, or the header (-1), back over the cached copy of them that failed its check (§17.8). The bytes are written with no writer held (§21.2).

Source

pub async fn cache_range( &self, file: &FileRef, first: i64, chunks: i64, name: FileName, bytes: Vec<u8>, ) -> Result<(), DbError>

Keep one verified range of chunks consecutive encrypted chunks from first, or the header (first = -1), durably before publishing its cache metadata in one transaction. The bytes are written with no writer held (§21.2), on a blocking worker that finishes even if the caller stops waiting.

Source

pub async fn trim_cache(&self, namespace: &str) -> Result<(), DbError>

Evict unpinned chunks in least-recently-read order, independently per namespace.

Source

pub async fn missing_bytes(&self, file: &FileRef) -> Result<u64, DbError>

Plaintext bytes absent from this namespace’s cache; headers and tags are excluded from application download progress. A file only on this device is wholly local.

Source

pub async fn budget(&self, namespace: &str) -> Result<u64, DbError>

The namespace’s budget, declared or since set.

Source§

impl FileDatabase

Source

pub fn uploads_in_flight(&self) -> InFlight

The files this process is sending now, which the upload worker marks as each attempt starts and ends (§17.9).

Source

pub fn downloads_in_flight(&self) -> InFlight

The files this process is downloading to keep whole now, which each pin’s download marks as it starts and ends (§17.8).

Source

pub async fn local_evidence<P: PendingValue>( &self, file: &FileRef, upload_subject: impl FnOnce(&FileLocation) -> P::Subject + Send + 'static, move_subject: impl FnOnce(MoveId) -> P::Subject + Send + 'static, ) -> Result<Option<LocalEvidence<P>>, DbError>
where P::Subject: Send,

The upload of a file this device uploads, its move, this device’s record about the upload’s bytes and its move’s record, read in one committed state: the local facts its status is judged with (§17.6). None when this device doesn’t upload the file.

Source

pub async fn fail_move<P: PendingValue>( &self, upload: i64, record: P, ) -> Result<(), DbError>

Fail a move because a user’s original changed before its upload (§17.3): none of its files switches, each stays on this device only, and its uploads retire, their stored bytes becoming deletion candidates. record is the move’s own and says which original. A move that already ended keeps its state.

Source

pub async fn clear_original<P: PendingValue>( &self, upload: i64, subject: P::Subject, checked: impl Fn(&P, &Path) -> bool + Send + 'static, ) -> Result<Option<PathBuf>, DbError>
where P::Subject: Send + 'static,

Clear the record subject names if checked says the read or upload of upload’s original that just succeeded settles it, by the record and the original’s path. The predicate and deletion share the pending transaction, which also ends the upload’s retry wait the failure armed. Returns the original’s path when it cleared.

Source

pub async fn retire_unlinked<S: Serialize + Send + 'static>( &self, in_flight: BTreeSet<ObjectId>, subject: impl Fn(&FileLocation) -> S + Send + 'static, ) -> Result<Vec<i64>, DbError>

Retire the uploads no file waits for any more, except those whose objects are in in_flight, whose attempts retire them as they end (§17.9). Each retired upload’s pending record goes with it, and its stored path becomes a deletion candidate unless something else protects it (§17.10). Returns the retired queue ids.

Source

pub async fn fail_download<P: PendingValue>( &self, record: P, ) -> Result<(), DbError>

Record this device’s first unmet condition for the stored bytes a pin downloads, replacing an earlier reason. It keeps no wait: only the app’s next pin or read tries again (§17.7).

Source

pub async fn clear_download_pending<P: PendingValue>( &self, subject: P::Subject, checked: impl Fn(&P) -> bool + Send + 'static, ) -> Result<(), DbError>
where P::Subject: Send + 'static,

Clear only conditions the completed download actually checked. The predicate and deletion share the pending transaction.

Source

pub async fn clear_upload_pending<P: PendingValue>( &self, object: (DeviceId, ObjectId), subject: P::Subject, checked: impl Fn(&P) -> bool + Send + 'static, ) -> Result<Option<RetrySubject>, DbError>
where P::Subject: Send + 'static,

Clear only conditions the completed local read actually checked. The predicate and deletion share the pending transaction. Any queued upload wait ends with it; return the upload subject so the caller can discard its in-memory timer.

Source

pub async fn fail_local_read<P, E>( &self, file: FileId, record: P, next: impl FnOnce(Option<RetryWait>) -> Result<RetryWait, E> + Send + 'static, ) -> Result<Option<(RetrySubject, RetryWait)>, E>
where P: PendingValue, E: From<DbError> + CarriesBug + Send + 'static,

Record a local source failure only while its upload remains queued. The retry is selected from the current upload wait and committed with the record, so concurrent upload completion cannot leave a stale failure. A next that fails records nothing and returns its own error; only a failed save fails the handle, as any lost pending state does (E5).

Source

pub async fn uploads(&self) -> Result<Vec<FileUpload>, DbError>

Durable queue: each upload some file still waits for.

Source

pub async fn all_uploads(&self) -> Result<Vec<FileUpload>, DbError>

Every queued upload, those no file waits for included.

Source

pub async fn bound_uploads(&self) -> Result<BTreeSet<i64>, DbError>

The queue ids of the bound uploads, which the pause leaves running (§17.4).

Source

pub async fn uploads_paused(&self) -> Result<bool, DbError>

Whether the app paused uploads, as persisted (E7).

Source

pub async fn writes_paused(&self) -> Result<bool, DbError>

Whether a self-replacement pauses this device’s writes, which holds a trailing upload’s completion until it ends (§12.3, §17.4).

Source

pub async fn unmetered_only(&self) -> Result<bool, DbError>

Whether the app moves files only on unmetered networks, as persisted (E7).

Source

pub async fn upload_work<P: PendingValue>( &self, subject: impl Fn(&FileLocation) -> P::Subject + Send + 'static, ) -> Result<Vec<(FileUpload, Option<P>)>, DbError>

Each queued upload with this device’s pending record about its file, read in one committed state: the reason an earlier attempt left decides whether automatic work retries it (§17.9).

Source

pub async fn abandoned_uploads<P: PendingValue>( &self, subject: impl Fn(&FileLocation) -> P::Subject + Send + 'static, ) -> Result<Vec<(FileUpload, Option<P>)>, DbError>

Each upload no file waits for any more that still records a provider session, with this device’s pending record about its file, read in one committed state: its session is aborted before it retires (§17.9).

Source

pub async fn forget_session(&self, id: i64) -> Result<(), DbError>

Forget the session of upload id once storage has aborted it, if no file waits for the upload: it then retires with the others (§17.9). One a file waits for again keeps its record, and its next attempt finds the session gone and starts another.

Source

pub async fn fail_upload<P: PendingValue>( &self, id: i64, record: P, retry: Option<RetryWait>, ) -> Result<(), DbError>

Record a failed attempt as this device’s pending record about its file, with its retry wait or none when it waits for a prerequisite or the app, in one transaction (§17.9, §19.1).

Source

pub async fn upload_chunk_hash( &self, location: &FileLocation, index: u64, ) -> Result<ContentHash, DbError>

Read the first-read plaintext hash of one queued chunk, keyed by the upload’s location and owned by the queue whatever its files became.

Source

pub async fn open_upload_source( &self, upload: &FileUpload, ) -> Result<Option<LocalFileStream>, LocalFileError>

Open the source an upload sends, from the facts its queue entry fixed at staging; later row changes cannot replace them. None means the upload is no longer queued. It is opened with no writer held.

Source

pub async fn record_session( &self, id: i64, session: SecretBytes, progress: UploadProgress, ) -> Result<(), DbError>

Persist the provider recording after each confirmed change in progress, with the bytes it records as confirmed, which coven_uploads gives the app (E4). Storage alone reads the recording, so the caller gives both from the same session.

Source

pub async fn complete_upload<S: Serialize + Send + 'static>( &self, id: i64, subject: S, ) -> Result<UploadCompletion, DbError>

Complete an upload once storage confirms its complete bytes (§17.9): one local transaction switches each file the upload stores to the cloud, as this device’s write, and removes the queue row, its chunk hashes, the copy kept for it and this device’s pending record about it. A file gone meanwhile switches nothing. Afterwards this device reads the files from the cache or storage. A write that can’t be made now fails the transaction, and the upload stays queued. An upload no file waits for any more, of a move that failed or was cancelled while it was sent, retires instead, storing no file.

Source

pub async fn reserve_cache_file( &self, file: &FileRef, name: FileName, ) -> Result<CacheReservation, DbError>

Reserve a whole cache file of file while it is written and checked, for a pin; a read-only handle caches individual chunks only.

Source

pub fn queued_work_changes(&self) -> DatabaseChanges

Observe the upload worker’s work: newly queued uploads, and uploads a file stopped waiting for. Subscribing before reading the work list prevents missed commits.

Trait Implementations§

Source§

impl<M: Mode> Clone for FileDatabase<M>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<M> Freeze for FileDatabase<M>
where <M as Sealed>::WriterParts: Freeze,

§

impl<M = Writer> !RefUnwindSafe for FileDatabase<M>

§

impl<M> Send for FileDatabase<M>

§

impl<M> Sync for FileDatabase<M>

§

impl<M> Unpin for FileDatabase<M>
where <M as Sealed>::WriterParts: Unpin,

§

impl<M> UnsafeUnpin for FileDatabase<M>
where <M as Sealed>::WriterParts: UnsafeUnpin,

§

impl<M = Writer> !UnwindSafe for FileDatabase<M>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,