pub trait BlobTransitionObserver: Send + Sync {
// Required methods
fn on_blob_upload_started<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn on_blob_uploaded<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait;
fn on_blob_upload_failed<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
error: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
// Provided methods
fn on_blob_upload_progress<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
bytes_done: u64,
bytes_total: u64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait { ... }
fn should_skip_uploads(&self) -> bool { ... }
fn on_root_made_remote<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait { ... }
fn on_root_made_local<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait { ... }
fn on_blob_materialize_progress<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
blob_id: &'life3 str,
done: u64,
total: u64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait { ... }
}Expand description
Notified about coven’s blob transitions, for host-specific bookkeeping and UI: per-blob upload progress while a make_remote uploads, per-blob materialize progress while a make_local copies files back, and a completion hook per direction the host turns into its own UI event.
The host no longer drives the transition — coven owns flipping the gate and
deciding when a cycle publishes — so this observer only reports. The upload
callbacks fire as the drain works: on_blob_upload_started before each
attempt, on_blob_upload_progress zero or more times as encrypted bytes reach
the cloud (backends that can’t report sub-file progress call it once at the end
with bytes_done == bytes_total), on_blob_uploaded on success (notification
only — coven, not the host, flips the gate and breaks the drain to publish),
and on_blob_upload_failed when an attempt fails and its entry stays queued.
on_root_made_remote / on_root_made_local fire whenever coven completes a
transition — including one resumed after a restart — so the host’s own
row-updated event survives a restart rather than being lost with an in-memory
flag. on_blob_materialize_progress moves a make_local’s per-file progress bar.
should_skip_uploads lets the host pause the upload pipeline without touching
the queue: the sync cycle consults it before draining so a paused queue still
accepts new entries but doesn’t drain ([upload::drain_uploads] checks once at
the top of each entry; in-flight uploads complete normally).
Required Methods§
Sourcefn on_blob_upload_started<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn on_blob_upload_started<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
An upload attempt for this blob is starting now.
Sourcefn on_blob_uploaded<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn on_blob_uploaded<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
The blob was uploaded to the cloud successfully — notification only. coven owns flipping the gate and breaking the drain to publish a completed make_remote.
Sourcefn on_blob_upload_failed<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
error: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_blob_upload_failed<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
error: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
An upload attempt failed; the entry remains queued for retry.
Provided Methods§
Sourcefn on_blob_upload_progress<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
bytes_done: u64,
bytes_total: u64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn on_blob_upload_progress<'life0, 'life1, 'async_trait>(
&'life0 self,
blob_id: &'life1 str,
bytes_done: u64,
bytes_total: u64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
bytes_done of bytes_total encrypted bytes have reached the cloud for
this in-flight blob. bytes_done is cumulative and monotonic within one
upload attempt. The default is a no-op so observers that don’t surface
sub-file progress don’t need a stub.
Sourcefn should_skip_uploads(&self) -> bool
fn should_skip_uploads(&self) -> bool
If true, the sync cycle skips the upload drain this round and
[upload::drain_uploads] short-circuits before pulling the next queued
entry. The default is false so existing implementations don’t need a stub.
Sourcefn on_root_made_remote<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_root_made_remote<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
coven completed a make_remote of (root_table, root_id): every blob is
uploaded and the gate is flipped true (the subtree publishes this cycle).
Fires for a restart-resumed completion too, so the host’s row-updated event
is not lost to a crash. The default is a no-op.
Sourcefn on_root_made_local<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_root_made_local<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
coven completed a make_local of (root_table, root_id): every blob is back
to a local file (a user file for user-provided, the local store for
host-provided), the gate is flipped false (the subtree retracts from peers),
and the cloud blobs are queued for tombstoning. The default is a no-op.
Sourcefn on_blob_materialize_progress<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
blob_id: &'life3 str,
done: u64,
total: u64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
fn on_blob_materialize_progress<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
root_table: &'life1 str,
root_id: &'life2 str,
blob_id: &'life3 str,
done: u64,
total: u64,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
done of total of a make_local’s blobs have been materialized back to a
local file, so the host can move a per-file progress bar. The default is a
no-op.