Skip to content

ledger

The unit ledger: workers of a split task claim units through atomic renames.

LedgerCounts dataclass

LedgerCounts(pending, claimed, done, total)

The number of units per state.

Ledger

Ledger(root, n_units)

A directory with pending/<i>, claimed/<i>@<worker> and done/<i>.

Workers touch heartbeats/<worker>, so that the claims of a worker which died without releasing them are found by the age of its heartbeat (release_stale).

Every transition is one os.rename, atomic on a local file system and on NFS v4, so a unit is held by at most one worker. On NFS the mount must be NFS >= 4.1 (sessions give renames exactly-once semantics; claim also tolerates a resent rename that answers ENOENT although it happened).

Open the ledger at root of n_units units (see create).

create classmethod

create(root, n_units)

Create the ledger, or open an existing one of the same size.

The ledger is built in a temporary directory and renamed, so it appears complete or not at all, also when several processes create it at once or one of them crashes.

Parameters:

Name Type Description Default
root Path

The ledger directory.

required
n_units int

The number of units, indices 0..n_units-1.

required

Returns:

Type Description
Self

The ledger.

Raises:

Type Description
ValueError

An existing ledger has another size.

claim

claim(worker)

Claim the lowest pending unit, or return None when none is pending.

complete

complete(index, worker)

Mark a unit claimed by worker as done.

release

release(index, worker)

Return a unit claimed by worker to pending.

release_all

release_all(worker)

Free every unit claimed by worker, as a restarted worker does.

Returns:

Type Description
list[int]

The indices released, sorted.

heartbeat

heartbeat(worker)

Touch the heartbeat file of worker, created with its directory lazily.

Its modification time is set by the file server, so the heartbeats of workers on different servers compare without their clocks.

Raises:

Type Description
OSError

The time of the file was not set.

release_stale

release_stale(stale_s, reference)

Return the claims of workers without a recent heartbeat to pending.

The heartbeat of reference is touched and its time is "now"; a claim of another worker which has no heartbeat or one older than now - stale_s is released. The claims of reference are never released.

Parameters:

Name Type Description Default
stale_s float

Seconds after which a heartbeat is stale.

required
reference str

The worker which releases, e.g. the coordinator.

required

Returns:

Type Description
list[int]

The indices released, sorted.

Raises:

Type Description
OSError

The heartbeat of reference was not touched.

counts

counts()

The number of units per state.

claims

claims()

The claimed units by worker id, the indices sorted.

complete_ledger

complete_ledger()

Whether every unit is done.

missing

missing()

The units not done, sorted.