pub struct FillSession { /* private fields */ }Expand description
One in-flight fill of a total_bytes-byte blob rooted at root.
Holds a reference to the per-hash HashOutboard (captured by the cache admit
path via Self::capture, read by SessionOutboardReader), the pull’s
terminal outcome (Self::mark_ended / Self::outcome), the ranges this fill
covers (Self::set_covered), and the shared downstream frontiers the pull
leg paces against (Self::served_frontier / Self::serve_demand, awaited
through Self::downstream_watch). Shared
behind an Arc; every field is interior-mutable, so both legs hold
Arc<FillSession> and coordinate on it.
Implementations§
Source§impl FillSession
impl FillSession
Sourcepub fn new(root: Hash, total_bytes: u64) -> Arc<Self> ⓘ
pub fn new(root: Hash, total_bytes: u64) -> Arc<Self> ⓘ
Construct the fill session for a total_bytes-byte blob rooted at root,
with its served frontier at 0. An owning branch for a request that starts
past byte 0 uses Self::starting_at instead.
Sourcepub fn starting_at(root: Hash, total_bytes: u64, served_start: u64) -> Arc<Self> ⓘ
pub fn starting_at(root: Hash, total_bytes: u64, served_start: u64) -> Arc<Self> ⓘ
Construct the fill session for a total_bytes-byte blob rooted at root,
with its served frontier at served_start: the ABSOLUTE content offset the
request starts at, so a non-zero-offset request shows no phantom lead. The
session starts with a private per-hash outboard, replaced by the registry’s
canonical one at registration.
Sourcepub fn set_pull_handle(&self, handle: JoinHandle<()>)
pub fn set_pull_handle(&self, handle: JoinHandle<()>)
Park the owner’s pull-thread handle on the session so whichever observer leaves LAST joins it. Called once, on an owning branch, right after the pull thread is spawned. The pure-attach path never calls this — it drives no pull of its own.
Refuses to overwrite an already-parked handle: a session has exactly one owning
pull, so a second park cannot happen — but if a future regression called this
twice, overwriting would DROP the first handle and detach its thread, orphaning
a pull that keeps paying/draining. So keep the first (the one the last-out
observer will join) and debug_assert the double-park loudly in tests/dev.
Sourcepub fn set_covered(&self, covered: ChunkRanges)
pub fn set_covered(&self, covered: ChunkRanges)
Set the chunk ranges this fill will produce. Called once at registration,
before the pull streams — the registry reads it to plan observer attach and
to answer Self::range_still_live.
Sourcepub fn total_bytes(&self) -> u64
pub fn total_bytes(&self) -> u64
The blob’s total byte length. The attach path signs its StreamResponse
from this without re-running the upstream header handshake — the session
already knows the geometry from its BaoTree.
Sourcepub const fn served_start(&self) -> u64
pub const fn served_start(&self) -> u64
The ABSOLUTE content offset this session’s owning request starts at.
Sourcepub fn served_paid(&self) -> u64
pub fn served_paid(&self) -> u64
The current PAID content frontier (absolute): how far the observers of this fill have paid, and therefore how far past it the pull may run.
Sourcepub fn observer_count(&self) -> usize
pub fn observer_count(&self) -> usize
The live observer count (pull owner + attached serve legs).
Sourcepub fn is_cancelled(&self) -> bool
pub fn is_cancelled(&self) -> bool
Whether the pull has been cancelled because the last observer left.
Sourcepub const fn cancel_token(&self) -> &CancellationToken
pub const fn cancel_token(&self) -> &CancellationToken
The pull leg’s cancellation token — it selects on this to abort ingest when the last observer leaves before the pull completes.
Sourcepub fn outboard_reader(self: &Arc<Self>) -> SessionOutboardReader
pub fn outboard_reader(self: &Arc<Self>) -> SessionOutboardReader
Mint a serve-side SessionOutboardReader over this hash’s shared outboard.
The reader snapshots the (already-adopted) outboard and holds this session so
its termination race can reach the registry. A serve path attaches the store
(SessionOutboardReader::with_store_fallback); without it, a load of a node
no live fill captures fails.
Sourcepub const fn served_frontier(&self) -> &Frontier
pub const fn served_frontier(&self) -> &Frontier
The shared PAID content frontier the pull leg’s pacer bounds against.
Sourcepub fn advance_served(&self, served: u64)
pub fn advance_served(&self, served: u64)
Raise the PAID content frontier to served after a downstream voucher batch
commits, waking the parked pull if it moved. A lower value changes nothing,
so N observers advancing one shared frontier never regress each other.
Sourcepub fn extend_served_from(&self, offset: u64, served: u64)
pub fn extend_served_from(&self, offset: u64, served: u64)
Raise the PAID content frontier to served on behalf of an observer whose
delivery starts at content offset, but only when this session’s frontier
already reaches offset.
Under partial-overlap coalescing an observer consumes a SUFFIX of this fill’s
covered range, starting at offset. Its payment extends this fill’s paid
PREFIX only once that prefix reaches offset. Before that, the bytes in
[frontier, offset) are unpaid, and raising the frontier past them would let
the pull run its window over bytes no observer of this fill has paid for.
Sourcepub fn downstream_watch(&self) -> DownstreamWatch
pub fn downstream_watch(&self) -> DownstreamWatch
A read-only watch over both downstream frontiers, for a pull leg to pace against and park on.
Sourcepub const fn serve_demand(&self) -> &Demand
pub const fn serve_demand(&self) -> &Demand
The serve demand of this fill. When its nearest value lies within one chunk group past a pull’s frontier, that pull’s pacer draws one window floor even with its window full; a demand further out is ignored.
Sourcepub fn demand_slot(self: &Arc<Self>) -> DemandSlot
pub fn demand_slot(self: &Arc<Self>) -> DemandSlot
Mint the DemandSlot one serve leg reading this fill stands its demand
through. Under coalescing the awaited byte may belong to a sibling fill of
the hash, so the slot routes each demand through the registry.
Sourcepub fn liveness_signal(&self) -> Arc<Notify> ⓘ
pub fn liveness_signal(&self) -> Arc<Notify> ⓘ
The per-hash liveness signal, notified whenever any session for this hash
ends or is cancelled. A serve-side data reader awaits it (alongside the
present-range watch) so a read of a range no live pull will fill settles
rather than hanging: served from the store when it holds the bytes, failed
otherwise. Handed out as an owned Arc<Notify> so the node’s data reader
need not name the cache-private HashOutboard.
Sourcepub fn range_still_live(&self, range: &ChunkRanges) -> bool
pub fn range_still_live(&self, range: &ChunkRanges) -> bool
Whether any LIVE fill of this hash still covers range, so a not-yet-present
node / leaf in range may still be filled. A registry-bound session consults
EVERY live session for the hash (the N-fill generalization); a standalone
session (unregistered, in tests) is the only fill, so it answers from its own
liveness. Returns false when nothing live covers range — the caller then
fails the read instead of hanging.
Sourcepub fn capture(&self, node: TreeNode, pair: (Hash, Hash))
pub fn capture(&self, node: TreeNode, pair: (Hash, Hash))
Capture one internal node’s (left, right) hash pair into the per-hash
outboard. Idempotent; a leaf (no outboard slot) is ignored. Every
admit_bao_stream for the hash, from any pull or source, calls this — so the
one shared buffer accumulates the whole tree’s proof.
Sourcepub fn capture_many(
&self,
pairs: impl IntoIterator<Item = (TreeNode, (Hash, Hash))>,
)
pub fn capture_many( &self, pairs: impl IntoIterator<Item = (TreeNode, (Hash, Hash))>, )
Capture a batch of node pairs into the per-hash outboard in one shot, waking parked serve legs once for the batch rather than once per node. The admit path hands each leaf’s run of proof nodes here just before the leaf, so a serve leg reads a leaf’s proof as soon as that leaf arrives, with at most one wake per leaf.
Sourcepub fn mark_ended(&self, result: Result<(), FillError>)
pub fn mark_ended(&self, result: Result<(), FillError>)
Record the pull leg’s terminal outcome and wake parked readers. Idempotent
on the wake; the outcome is set once by the pull leg on its single exit.
Fires the per-hash liveness so a reader awaiting a range this fill covered
re-checks Self::range_still_live at once.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for FillSession
impl RefUnwindSafe for FillSession
impl Send for FillSession
impl Sync for FillSession
impl Unpin for FillSession
impl UnsafeUnpin for FillSession
impl UnwindSafe for FillSession
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more