pub struct PullJobDir { /* private fields */ }Expand description
One pull’s directory: its descriptor, and the files around it.
Implementations§
Source§impl PullJobDir
impl PullJobDir
Sourcepub fn open(path: impl Into<PathBuf>) -> Result<Self, PullError>
pub fn open(path: impl Into<PathBuf>) -> Result<Self, PullError>
Open the job directory at path, reading its descriptor.
An undecodable descriptor is reported, never moved aside: another process may still be pulling what it describes, and a reader that quarantines it would take the job away from every client at once.
Sourcepub fn claim(&self) -> Result<Option<PullLock>, PullError>
pub fn claim(&self) -> Result<Option<PullLock>, PullError>
Take the job for this process, or None when someone else holds it.
A single refusal is not proof of another worker: a reader probing liveness holds a shared lock for a moment, and that is enough to deny an exclusive claim. A caller concluding “already owned” should try a few times over a short window first.
Sourcepub fn worker_alive(&self) -> bool
pub fn worker_alive(&self) -> bool
Whether a worker still owns this job.
The test is the lock, not the pid: a pid can be reused, and the operating system releases an advisory lock even when the process is killed or panics. The probe takes a shared lock, which a worker’s exclusive one still blocks, but which two readers can hold at once: probing with an exclusive lock would make concurrent readers report each other as the worker.
A lock file that exists but cannot be opened counts as alive. Calling a live pull dead is the costlier mistake, since it invites a second worker onto the same download.
Sourcepub fn stored_status(&self) -> PullStatus
pub fn stored_status(&self) -> PullStatus
The record as written, without the liveness rule applied.
A missing record reads as queued, which is what a job whose worker
never got started is. An undecodable one reads the same way rather than
being quarantined: this file is a rewritten view of live state, not a
store of truth, and a running worker replaces it within the second.
Sourcepub fn status(&self) -> PullStatus
pub fn status(&self) -> PullStatus
The record as it is true right now: a job a worker was meant to be
holding, with nobody holding it, is interrupted.
A queued job counts only once a worker has written its pid, which it
does after it has everything it needs to run. Before that the job has
simply not been picked up yet, and a client that read it as interrupted
would start a second worker on top of one still starting, or on top of
one that stood down because another worker owns the same reference.
Sourcepub fn abandoned(&self, now_ms: i64, grace_ms: i64) -> bool
pub fn abandoned(&self, now_ms: i64, grace_ms: i64) -> bool
Whether the job is waiting for a worker that is not coming: queued with
no pid written, nobody holding the lock, and grace_ms past its last
write, by which time a worker on its way would have claimed it.
This is the one state the liveness rule cannot speak for. A worker writes
its pid as soon as it holds the job, so queued without one means
nothing has taken the job yet; only time tells a job still being picked
up from one whose worker died on the way.
Sourcepub fn abandoned_by(
&self,
status: &PullStatus,
now_ms: i64,
grace_ms: i64,
) -> bool
pub fn abandoned_by( &self, status: &PullStatus, now_ms: i64, grace_ms: i64, ) -> bool
abandoned for a record already read, so a reader
that holds one does not read it again; the lock is still probed.
Sourcepub fn write_status(&self, status: &PullStatus) -> Result<(), PullError>
pub fn write_status(&self, status: &PullStatus) -> Result<(), PullError>
Write status atomically, so a reader sees the old record or the new one
and never half of either.
A job whose directory has been swept is reported gone rather than recreated: an atomic write makes its parents, and a worker writing into a removed job would leave a directory no listing can see.
Sourcepub fn update_status(
&self,
now: i64,
change: impl FnOnce(&mut PullStatus),
) -> Result<PullStatus, PullError>
pub fn update_status( &self, now: i64, change: impl FnOnce(&mut PullStatus), ) -> Result<PullStatus, PullError>
Read the stored record, hand it to change, and write it back stamped
now. Saves the caller from carrying the record between writes; the
worker is the only writer, so no two of these can interleave.
Sourcepub fn append(&self, kind: PullEventKind, now: i64) -> Result<(), PullError>
pub fn append(&self, kind: PullEventKind, now: i64) -> Result<(), PullError>
Append kind to the history, stamped now. A file whose last line was
torn off mid-write gets its newline back first, so the damage stays on
the line it happened to.
Sourcepub fn events(&self) -> Vec<PullEvent>
pub fn events(&self) -> Vec<PullEvent>
The history, oldest first. A line that will not decode is skipped rather than sinking the rest of the file, and that includes a line that is not even valid text.
Sourcepub fn control(&self) -> Option<PullControl>
pub fn control(&self) -> Option<PullControl>
What a client has asked the worker to do, if anything.
Sourcepub fn request(&self, control: PullControl) -> Result<(), PullError>
pub fn request(&self, control: PullControl) -> Result<(), PullError>
Ask the worker for control.
Sourcepub fn clear_control(&self, honoured: PullControl) -> Result<(), PullError>
pub fn clear_control(&self, honoured: PullControl) -> Result<(), PullError>
Drop the control the worker has honoured, leaving a later one alone: a cancel that arrived while a pause was being honoured is still waiting to be read, and deleting it would lose it silently.
Sourcepub fn remove(&self) -> Result<(), PullError>
pub fn remove(&self) -> Result<(), PullError>
Delete the job’s directory. The weights it fetched are not touched: they belong to the model store, not to the job.
Sourcepub fn forget(&self) -> Result<(), PullError>
pub fn forget(&self) -> Result<(), PullError>
Forget an ended job: remove once the record has
ended and no worker holds the lock. A worker holds the lock until it
exits, a moment after it settles the record, so a record that reads
ended can still be under a worker, and deleting the directory then
would leave a partial one behind. The rule every collector follows,
the sweep included.
Trait Implementations§
Source§impl Clone for PullJobDir
impl Clone for PullJobDir
Source§fn clone(&self) -> PullJobDir
fn clone(&self) -> PullJobDir
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more