exlab_wizard.sync.nas_client#

NAS sync client. Backend Spec §7.1, §7.3.

The NASSyncClient is the public surface of the NAS sync subsystem. It wires together the durable queue, the transport drivers, the SHA-256 verifier, the bandwidth scheduler, the cleanup interlocks, and the Pre-Sync Gate.

Per §7.1 the client is an in-process module of the FastAPI app; there is no separate daemon. Workers are asyncio tasks; the queue file is the durable record so a server restart does not lose pending work.

Classes

NASSyncClient(*, config, queue_db, ...[, ...])

Durable, per-equipment NAS sync queue with Pre-Sync Gate.

SyncJobHandle(job_id, state, run_path[, ...])

Lightweight handle returned by NASSyncClient.enqueue().

class exlab_wizard.sync.nas_client.NASSyncClient(*, config, queue_db, validator, cache_creation, verifier=None, worker_poll_interval_s=0.05, push_callable_factory=None, hashsum_callable_factory=None, remote_stat_callable=None)[source]#

Bases: object

Durable, per-equipment NAS sync queue with Pre-Sync Gate.

Backend Spec §7.1, §7.3.

Lifecycle:

  • init() opens the queue DB, replays any in-flight jobs, and starts a single background worker task.

  • enqueue() runs the Pre-Sync Gate, gates the run if needed, and otherwise inserts a QUEUED row.

  • close() cancels the worker and closes the DB.

The worker loop is a simple “pick the oldest QUEUED whose next_attempt_at has passed” scheduler with at-most-one inflight job at a time. This keeps determinism for tests; production deployments can extend to per-equipment parallelism without changing the public API.

Parameters:
async close()[source]#

Stop the worker and close the queue DB. Idempotent.

Return type:

None

async enqueue(run_path)[source]#

Pre-Sync Gate -> if hard-tier finding without override, mark sync_status='blocked_by_validation'. Otherwise insert a QUEUED row.

Returns a SyncJobHandle. The handle’s state is either SyncHandleState.BLOCKED or SyncHandleState.QUEUED.

Parameters:

run_path (Path)

Return type:

SyncJobHandle

async force_verify(run_path)[source]#

Recompute the local manifest and verify against itself.

Used by the Settings “verify integrity” action. Does not advance the queue state.

Parameters:

run_path (Path)

Return type:

VerifyResult

async init()[source]#

Open the queue and start the worker task. Backend Spec §7.1.2.

Return type:

None

async retry(job_id)[source]#

Re-arm a FAILED job. Backend Spec §7.1.5 (Problems-tab Retry).

Parameters:

job_id (str)

Return type:

None

async status(run_path)[source]#

Return the queue state of the job for run_path.

"none" when no job exists; otherwise the underlying SyncJobState value.

Parameters:

run_path (Path)

Return type:

str

class exlab_wizard.sync.nas_client.SyncJobHandle(job_id, state, run_path, blocking_findings=())[source]#

Bases: object

Lightweight handle returned by NASSyncClient.enqueue().

job_id is empty when the gate blocked enqueue (the on-disk sync_status will reflect the block). blocking_findings is present iff state == BLOCKED.

Parameters:
blocking_findings: tuple[Finding, ...]#
job_id: str#
run_path: str#
state: SyncHandleState#
class exlab_wizard.sync.nas_client.SyncJobState(*values)[source]#

Bases: StrEnum

State machine for a sync job. Backend Spec §7.1.2.

AWAITING_VERIFY = 'awaiting_verify'#
CLEANED = 'cleaned'#
CLEANUP_ELIGIBLE = 'cleanup_eligible'#
FAILED = 'failed'#
QUEUED = 'queued'#
RUNNING = 'running'#
VERIFIED = 'verified'#