Skip to main content

PullJobDir

Struct PullJobDir 

Source
pub struct PullJobDir { /* private fields */ }
Expand description

One pull’s directory: its descriptor, and the files around it.

Implementations§

Source§

impl PullJobDir

Source

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.

Source

pub fn path(&self) -> &Path

The directory itself.

Source

pub fn id(&self) -> &str

The job id.

Source

pub fn job(&self) -> &PullJob

The descriptor.

Source

pub fn lock_path(&self) -> PathBuf

The lock a worker holds for as long as it owns this job.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn control(&self) -> Option<PullControl>

What a client has asked the worker to do, if anything.

Source

pub fn request(&self, control: PullControl) -> Result<(), PullError>

Ask the worker for control.

Source

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.

Source

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.

Source

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

Source§

fn clone(&self) -> PullJobDir

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for PullJobDir

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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.

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.