研究室の Windows 機が夜間に眠らせている計算資源を使うための、汎用の分散計算基盤。
SMB 共有 (NAS) の上の spool を唯一の合意点にし、各 PC の worker が job を取りに来て計算し、成果物と受領書 (receipt) を共有に置く。
中央 server も DB も無い。Temari (STEM-EDX 内殻イオン化テーブル生成) の tools/jobq/ として育ったものを独立させた。
夜間に他人の眠っている機械を借りて計算を回すので「夜なべ」。リポ名・表示名は先頭大文字 Yonabe、識別子は小文字 yonabe。
利用者に見える語は campaign ⊃ job (⊃ epoch ⊃ attempt) と recipe pack ⊃ recipe だけ (作者決定 2026-09-06)。
campaign = 同じ recipe で走らせる job の集合 (manifest に job の一覧と code / contract / pack を pin)。job = 1 つの仕事 (中身は recipe が決める)。
epoch = job の発行回数 (再発行で進む)、attempt = 同じ epoch の中の実行回数 — どちらも安全に計算するための仕組みで、利用者が気にする必要は無い。
recipe = job の走らせ方の定義 (plan / run / verify / publish の hook と停滞閾値・成果物の規則を書いた record)。
⚠ code / CLI / 契約の識別子は歴史的な名前のまま: task (= recipe)、ticket / base (= job × epoch)。
- job の取り合いは rename と読み直しで決める (
queue/→running/の no-clobber rename の後、宛先がある・元が無いことを読み直して勝者を確定する。⚠ SMB では rename だけでは排他にならない)。所有の正典は fence (下)。lock server は要らない。 - worker は bash + Python (Git for Windows の MSYS bash と
queuectl.pyzの zipapp)。各 PC は共有直下のRegister.cmdをダブルクリックするだけで参加し、Unregister.cmdで抜ける (Task Scheduler に登録、再起動しても続く)。 - recipe pack (内部名 task pack): job の走らせ方の定義 = recipe (内部名 task) を種類ごとに
packs/<name>/に置き、.pyzに固めて共有に置く。core は recipe 名で分岐しない (原則 A: 汎用層は recipe の中身を見ない)。 - fence (所有の世代鎖) で二重実行を防ぎ、reaper (1 台) が沈黙した worker の job を回収して再発行する (epoch が進む)。
- 稼働率の規則 (
control/load: 曜日 × 時間帯 × host ごとの slot 数) と PAUSE で、昼は控えめに・夜は全開に、を共有 file 1 つで切り替える。 - 停滞の検出 (無音の閾値は代理負荷ではなく本物の較正から) と cancel (走行中でも回収して terminal に)。
- GUI (PySide6、読み取り専用が既定): 参加 PC と使用率、campaign の進捗と ETA、job ごとの run log / events log の閲覧、稼働率の編集 (錠前を外したときだけ)。
- 失敗モード台帳: 設計が賭けている前提 (rename の原子性、JSON の型、schema の閉世界、…) を 100 余りの失敗モードに分け、各検査がどの面を踏んだかを辺で結ぶ。検査は 20 suite / 1,500 余りの assertion。
| dir / file | 何 |
|---|---|
yonabe/ |
本体 (Python package)。queuectl.pyz はこれを build_queuectl.sh で固めたもの |
yonabe_worker.sh / yonabe_reaper.sh |
各 PC で走る worker / reaper (bash)。判定は全部 queuectl に聞く |
share/ |
共有直下に置くもの (Register.cmd / Unregister.cmd / Enable-RPS.cmd / README.txt) と setup/ (bootstrap.ps1 等)。deploy_setup.sh <ROOT> が配る |
admin/ |
管理者だけの道具 (遠隔登録、reaper の登録、資格情報の保存)。site 固有の値は *.local.txt (git 追跡外) で |
packs/ |
recipe pack の source (yonabe-tasks = 自己検査用、temari-tasks = Temari の adapter) |
gui/ |
GUI (py -3.14 -m gui //<nas>/yonabe/spool) |
test/ |
検査 suite (py -3.14 test/<suite>.py。PYTHONIOENCODING=utf-8 で) |
tools/ |
台帳の検査 (check_failure_ledger.py)、共有の原始操作の実測 (unc_probe/)、内部情報の検査、公開用 snapshot |
docs/boundary.md |
設計の正本 (契約・失敗モード・作者決定の全部) |
⚠ 開発の作業記録 (引き継ぎ文書、設計 note、Temari との便り、失敗モード台帳の data、site 固有の値) は非公開で、この公開リポには含まれていない。docs/boundary.md から handover/ / notes/ へのリンクはそのため切れている。
- NAS に共有 (例
\\<nas>\yonabe) を作り、deploy_setup.sh //<nas>/yonabeでsetup/packs/admin/と共有直下の cmd を配る (bash から。build_queuectl.shが先)。 - 各 PC で共有直下の
Enable-RPS.cmd(1 回、WinRM の有効化) →Register.cmd(UAC は はい)。C:\yonabe\logs\に[PASS]が出れば参加している。 - 1 台だけ
admin\register-reaper.cmdで reaper 兼務にする。 - campaign を出す:
py -3.14 -m yonabe.cli new-campaign <spool> <pack.pyz> <name> <recipe (内部名 task)> jobs.json [--contract f] [--code-sha256 x]→issue <spool> <pack.pyz> <name>。 - 見る:
py -3.14 -m gui //<nas>/yonabe/spool(書くには画面の「共有への書込みを許す」を入れる)。
前提: Windows 10/11、Git for Windows (最近のもの — 2018 年版の MSYS では /proc/<pid>/stat が読めず runner の telemetry が欠ける)、Python 3.11 以上 (site 標準は 3.14)、GUI は PySide6。
PYTHONIOENCODING=utf-8 py -3.14 test/yonabe_worker_test.py # 1 suite (130 case、数秒)
PYTHONIOENCODING=utf-8 py -3.14 test/yonabe_wiring_test.py # 実 bash worker の配線 (68 case、約 12 分)
py -3.14 gui/tests/run_all.py # GUI の 7 suite
py -3.14 tools/check_failure_ledger.py # 台帳の整合 (台帳 data は非公開なので公開リポでは走らない)
- 検証した規模: 1 fleet = 16 台 / 134 slot、本番形の campaign は 1 slot/host で 16 job (停滞閾値 1,800 s の較正、kill 0)。多 slot の並列度 (夜間規則の ~114 slot) で本番 task を走らせた実績はまだ無い。
- SMB の読み取り遅延: Windows の redirector は閉じた後 10〜15 s の間、同じ path の open を再利用し、rename 前の中身を返すことがある (実測 = 10 s 間隔の再読で 90 回中 69 回古い)。GUI の読み手は
CopyFileW経由で回避しているが、core (reaper / barrier) は間隔が長い (60 s / 600 s) ことに頼っている。 - status の書込みは同期で上限が無い: 共有が固まると worker の心跳 loop ごと止まる。60 s の上限は次の setup 世代で入れる (未配備)。
- GC は無い: 終端した job・receipt・log は消さない。共有と各 PC の空き容量は人が見る。
- 共有の途絶: NAS 側 (smbd) の一過性の障害で 15 台の status 更新が 6 分止まった実績が 1 回ある。reaper の
claim_timeout(1,800 s、2 strike) はそれより十分長い。 - 検査の前提が site に依存するもの: UNC の 2 writers の検査 (
unc_probe pair) は 2 台の host、ENOSPC の検査 (unc_probe enospc) は quota 付きの共有が要る。2018 年版の MSYS では runner の telemetry (CPU / RSS) が欠ける。 - recipe 側の契約: receipt の
calibration/observedの欄は recipe pack の record が宣言する。ここに載っている値は Temari のgen_productionで較正したもので、他の task はそれぞれ較正が要る。
MIT (see LICENSE).