exlab_wizard.orchestrator#
Orchestrator-mode runtime. Backend Spec §12, §13.
This package implements the orchestrator-mode features that activate when a
config.orchestrator.staging_root is configured or any nas-mode
equipment exists:
QuiescenceSyncPoller– background polling task that discovers every run pending NAS sync (orchestrator-staged andnas-mode) and enqueues a run once it has at least one quiescent file. It is the single operator-free auto-sync trigger (operator-free per-file NAS sync design, 2026-05-21), superseding the retired sentinel/manifestStagingWatcher.list_staged_runs()– read-side query that backs the Staging UI panel and theGET /stagingendpoint.
- class exlab_wizard.orchestrator.QuiescenceSyncPoller(*, config, nas_sync, sync_state_writer)[source]#
Bases:
objectPolls every run pending NAS sync and enqueues runs with eligible files.
Constructor dependencies are a
Config, aNASSyncClient-shaped sync client, and aSyncStateWriterused (read-only) to skip files already synced at their current(st_size, st_mtime_ns)signature.The start/stop/loop lifecycle mirrors the retired
StagingWatcher;poll_onceis exposed so tests can drive the poller synchronously.- Parameters:
config (
Config)nas_sync (
NASSyncLike)sync_state_writer (
SyncStateWriter)
- apply_config(config)[source]#
Swap the cached config in place so a live settings save applies.
poll_oncere-readsquiescence_minutes, the equipment list, the staging root, and the ignore globs fromself._configevery sweep, and_loop()re-readspoll_interval_secondseach iteration – so reassigning the config here makes every sync setting take effect on the next sweep without a tray relaunch.
- async poll_once(*, now_monotonic=None)[source]#
Run one discovery + quiescence + enqueue sweep.
now_monotonicis injectable so tests can drive the settle window with a controllable clock; production callers leave itNoneand the poller readstime.monotonic().Returns the list of run paths enqueued on this sweep (in discovery order) so tests can assert exactly which runs fired.
- class exlab_wizard.orchestrator.StagedRunSummary(path, current_state, equipment_id, project_name, run_kind, file_count, byte_total, elapsed_seconds_since_last_activity, last_activity_at)[source]#
Bases:
objectOne row in the orchestrator’s staging panel.
Backend Spec §13.8:
path– absolute filesystem path of the run leaf directory.current_state– the run’s derivedsync_state.jsonrollup (RunSyncStatevalue:"syncing"/"synced"/"cleared").equipment_id– the equipment segment of the run path.project_name– the LIMS project short id (parent dir).run_kind–"experimental"or"test".file_count/byte_total– size of the staged data.elapsed_seconds_since_last_activity– seconds betweennow_utcand the run directory’s mtime.last_activity_at– ISO-8601 string of the directory mtime.
- Parameters:
- exlab_wizard.orchestrator.list_staged_runs(*, config, staging_root=None, now_utc=None, sync_state_writer=None)[source]#
Enumerate every staged run with its derived lifecycle state.
staging_rootdefaults toconfig.orchestrator.staging_root. Returns an empty list whenstaging_rootis unset / missing.current_stateis the derivedsync_state.jsonrollup (RunSyncState):"syncing"/"synced"/"cleared".sync_state_writeris used to read each run’s per-file record; a defaultSyncStateWriteris constructed when the caller omits it. A run without async_state.json(no sync activity yet) rolls up to"syncing".This function is synchronous: it reads
sync_state.jsonvia the writer’s blockingSyncStateWriter.read_sync()so sync NiceGUI page handlers can call it without an event loop.Sort order: most recent directory mtime first.
- Parameters:
- Return type:
Modules
Operator-free, per-file quiescence-driven NAS sync poller. |
|
Operator-facing staging-clear helper. |
|
Read-only enumeration of runs pending NAS sync. |