Skip to content

feat: 自動保存/復元を起動時(env)で個別に、停止時の自動保存は実行時(REST/control)でも切替可能に - #73

Merged
MRyutaro merged 8 commits into
mainfrom
feat/toggle-auto-checkpoint
Jun 18, 2026
Merged

MRyutaro merged 8 commits into
mainfrom
feat/toggle-auto-checkpoint

Conversation

@MRyutaro

@MRyutaro MRyutaro commented Jun 17, 2026 •

Copy link
Copy Markdown
Owner

背景・課題

外部オーケストレーターが保存/復元のタイミングを制御するカーネルでは、起動時の自動復元・停止時の自動保存が邪魔になる。とくに ElasticHub の zero-reload マイグレーションでは、保存も復元も明示 API のタイミングに寄せたい:

  • 保存 … 旧カーネルを殺さず明示 API(POST /elastic_kernel/checkpoint)で保存する。その後の旧 pod 削除時に do_shutdown がまた自動保存すると、共有 NFS の同じ checkpoint を二重に上書きし teardown を遅らせる → 停止時の自動保存は切りたい。
  • 復元 … 移行先のカーネルをあらかじめ起動して待機させておき、切り替えの瞬間に明示 API(POST /elastic_kernel/restore)で任意のタイミングで復元する。復元をカーネル起動(__init__)と密結合させないことで、カーネルの再起動時間をクリティカルパスから排除できる → 起動時の自動復元も切り、復元タイミングを外から制御したい。

保存と復元は独立に切れる必要がある(用途によって片方だけ切りたいこともある)。単一フラグでは両者をまとめてしか切れない。

さらに、env 変数だけだと起動時にしかモードを決められない。「どの pod が移行対象か」は起動時には分からず、実行中のカーネルに対して任意のタイミングで切り替える手段も必要だった。ただし実行時に意味を持つのは「停止時の自動保存」だけで、復元は __init__ の一度きりのイベントなので起動後に切り替えても効果がない。そのため実行時の切り替えは保存側のみを対象とする。

変更内容

自動保存と自動復元を独立に切り替えられるようにした。フラグ名は「いつ起きるか」を表す(checkpoint_on_shutdown = 停止時の保存、restore_on_startup = 起動時の復元)。設定は2段構え:

1. 起動時の初期モード(環境変数)

環境変数 既定 効果
ELASTIC_KERNEL_CHECKPOINT_ON_SHUTDOWN 有効 0/false/no/off で停止時(do_shutdown)の自動保存を無効化
ELASTIC_KERNEL_RESTORE_ON_STARTUP 有効 同上で起動時(__init__)の自動復元を無効化
  • 両フラグは __init__(起動時)に一度だけ評価され self.checkpoint_on_shutdown / self.restore_on_startup の初期値になる。
  • 起動モードはログ Auto checkpoint: on_shutdown=on|off, on_startup=on|off で確認できる。

どう渡すか(誰がこの env を使ってカーネルを起動するか): これらはカーネルプロセスの環境変数なので、カーネルを起動する側がプロセスの環境に載せる。素の POST /api/kernels の body では任意の env を受け取れない点に注意(別途プロビジョナ等が必要)。実用的には次のいずれか:

  • singleuser pod / サーバープロセスの環境に設定する(最も手軽・推奨)。JupyterHub なら KubeSpawner の environment などで pod に与えれば、その上で起動する全カーネルが継承する。「全 elastic カーネルで停止時保存 OFF」のような一括設定はこれで済む。
  • カーネル起動 API に env を渡す。jupyter_client の KernelManager.start_kernel(env=...) や、ElasticHub の elastic_id_shim が同一 kernel_id でカーネルを起動する km.start_kernel(..., env=...) 経路に os.environ +上書きを載せる。pod 単位ではなくカーネル単位でモードを変えたいときはこちら。
import os
env = dict(os.environ, ELASTIC_KERNEL_CHECKPOINT_ON_SHUTDOWN="0")
# kernel_manager.start_kernel(env=env) など、起動 API に env として渡す

2. 実行時の上書き(control メッセージ / REST)— 停止時の自動保存のみ

起動後にモードを変えたい場合、走行中のカーネルへ切り替えを送れる。対象は停止時の自動保存のみ(復元は起動時に決まるので実行時の対象外)。

  • control メッセージ elastic_set_checkpoint_on_shutdown … {enabled: bool} を送ると self.checkpoint_on_shutdown を差し替え、更新後の現在値を返す。enabled 省略時は現在値を返すだけの read-only 照会。
  • REST POST /elastic_kernel/checkpoint_on_shutdown … checkpoint/restore と同じ流儀でオーケストレーターから HTTP で叩ける(body は enabled・bool・必須。無いと 400)。GET /elastic_kernel/checkpoint_on_shutdown?kernel_id=<id> で read-only に現在値を照会できる。
  • フラグの読み書きだけで user_ns に触れないため、保存/復元と違いメインループの空き待ちが不要で、セル実行中でも割り込んで切り替えられる。

無効化しても、明示的な保存/復元(control メッセージ・REST API)は引き続き機能する。

ElasticHub での使い分け

全 elastic カーネルを auto(既定)のまま起動しておき、移行対象に決めた瞬間にその pod だけ実行時に停止時の自動保存を false へ倒す、という流れにできる。移行対象では保存・復元とも明示 API に寄せ、とくに復元は移行先カーネルを先に起動して待機させておき切り替え時に明示復元することで、カーネルの再起動時間をクリティカルパスから外す。env を起動時に固定する方式と違い「移行する pod だけ手動」を後から選べるので、culling 等の通常停止で保存されなくなる副作用を移行対象以外に及ぼさずに済む。

検証

  • flake8 クリーン、black/isort 適用済み、mypy issues なし
  • pytest 全体: 97 passed, 16 skipped(skip は既存)

🤖 Generated with Claude Code

https://claude.ai/code/session_014fHMAFLuxVkdQ1u4PAU3Sr

MRyutaro and others added 2 commits June 17, 2026 17:46
…store

外部オーケストレーターがマイグレーションを制御するカーネル(ElasticHub の
クラウドバースティングでクラウド→オンプレへ状態を移すケース等)では、起動時の
自動復元・停止時の自動保存が転送やハンドシェイクの順序制御を壊すことがある。

環境変数 ELASTIC_KERNEL_AUTO_CHECKPOINT で、起動時の自動 restore と停止時の
自動 save をまとめて無効化できるようにする(デフォルトは従来どおり自動有効)。
"0"/"false"/"no"/"off"(大文字小文字・前後空白は無視)で無効化。control メッセージ
/REST による明示的な checkpoint/restore は無効化後も引き続き機能する。

設定はカーネル単位(プロセス環境変数)なので、オーケストレーターがマイグレーション
対象のカーネルを起動するときにだけ付与すればよく、通常ユーザーのカーネルは影響を
受けない。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ElasticHub の zero-reload マイグレーションでは、保存と復元で必要な向きが逆になる:
旧カーネルを殺さず明示 API で保存するため停止時の自動保存は不要(共有 NFS の
checkpoint を二重上書きし teardown を遅らせる)だが、復元は新 pod の __init__
自動ロード(elastic_id_shim の同一 kernel_id 起動)に依存しており有効のまま使いたい。

単一の ELASTIC_KERNEL_AUTO_CHECKPOINT では両方まとめてしか切れず restore が壊れる
ため、ELASTIC_KERNEL_AUTO_SAVE(停止時保存)と ELASTIC_KERNEL_AUTO_RESTORE(起動時
復元)に分割し、独立して無効化できるようにする。両フラグは __init__ で一度だけ
評価され固定される。明示 API / control メッセージによる保存・復元は無効化後も機能する。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@MRyutaro MRyutaro changed the title feat: ELASTIC_KERNEL_AUTO_CHECKPOINT で自動 checkpoint/restore を切り替え可能に feat: 自動保存/復元を AUTO_SAVE / AUTO_RESTORE で個別に切り替え可能に Jun 17, 2026
env 変数 (ELASTIC_KERNEL_AUTO_SAVE / AUTO_RESTORE) は「起動時の初期モード」を
決めるだけで起動後は変えられなかった。走行中のカーネルに対して切り替えられるよう、
control メッセージ elastic_set_auto_mode と REST POST /elastic_kernel/auto_mode を
追加する。

- kernel.py: _set_auto_mode(auto_save/auto_restore のうち送られたフラグだけを
  bool 正規化して self へ反映し現在値を返す)と control ハンドラ
  _on_set_auto_mode_request を追加。user_ns に触れないためメインループ待ち不要で、
  セル実行中でも割り込んで切り替えられる。
- serverextension.py: AutoModeHandler を追加(auto_save/auto_restore は bool 必須・
  最低一方必須、_send_and_await にペイロードを渡せるよう拡張)。
- tests: _set_auto_mode のフラグ差し替え/据え置き/bool 正規化、control ハンドラの
  reply、auto_mode エンドポイント登録を検証。
- docs/CHECKPOINT_API.md, CLAUDE.md: 起動時の初期モード(env)と実行時の上書き
  (control/REST)の2段構えとして整理。全 pod を auto 起動し移行対象だけ実行時に
  手動へ倒す ElasticHub 運用を追記。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MG1wUCxFFyr1XVkTgZxUcN
@MRyutaro MRyutaro changed the title feat: 自動保存/復元を AUTO_SAVE / AUTO_RESTORE で個別に切り替え可能に feat: 自動保存/復元を起動時(env)+実行時(control/REST)で個別に切り替え可能に Jun 17, 2026
MRyutaro and others added 5 commits June 18, 2026 09:05
「起動時の自動復元はそのまま使う(__init__ 自動ロードに依存)」という記述は意図と
食い違っていた。正しくは、カーネルをあらかじめ起動して待機させ、切り替えの瞬間に
明示 API で任意のタイミングで復元することで、カーネルの再起動時間をクリティカルパス
から排除する。移行対象カーネルは自動保存・自動復元をともに切り、保存も復元も明示 API
のタイミングに寄せる。docs/CHECKPOINT_API.md と CLAUDE.md の該当記述を修正。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
POST は切り替え専用で、現在の auto_save/auto_restore を読むだけの手段が無かった。
AutoModeHandler に read-only の GET を追加(空ペイロードで control メッセージを送ると
カーネルは何も変更せず現在値を返す)。kernel_id はクエリ引数で渡す。

- serverextension.py: AutoModeHandler.get を追加、docstring/ログを GET|POST に更新
- tests: 空フラグでの _set_auto_mode が据え置きで現在値を返すこと、GET/POST 両対応を検証
- docs/CHECKPOINT_API.md: GET エンドポイント・クエリ引数・照会の使用例を追記

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
enable_server_extension() の起動ログが checkpoint/restore のみで、後から追加した
auto_mode エンドポイントが抜けていたので追記する。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntime toggle to save

実行時に意味を持つのは「終了時の自動保存」だけ(復元は __init__ の一度きりの
イベントで、起動後の切り替えは no-op)だったため、実行時 API を保存側に絞り、
名前を「いつ起きるか」が伝わる形に統一した。

- env / 属性: ELASTIC_KERNEL_AUTO_SAVE → ELASTIC_KERNEL_CHECKPOINT_ON_SHUTDOWN
  (self.checkpoint_on_shutdown)、ELASTIC_KERNEL_AUTO_RESTORE →
  ELASTIC_KERNEL_RESTORE_ON_STARTUP (self.restore_on_startup)
- REST: GET|POST /elastic_kernel/auto_mode を廃止し
  GET|POST /elastic_kernel/checkpoint_on_shutdown を追加。POST は {enabled: bool}
  のみ(auto_restore の実行時書き込み = no-op を撤去)。GET は read-only 照会
- control: elastic_set_auto_mode → elastic_set_checkpoint_on_shutdown
- ハンドラ AutoModeHandler → CheckpointOnShutdownHandler、
  _set_auto_mode → _set_checkpoint_on_shutdown 等を改名
- docs/CHECKPOINT_API.md・CLAUDE.md・テストを追従。宙ぶらりんだった
  「次のとおり」の一文も解消

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014fHMAFLuxVkdQ1u4PAU3Sr
@MRyutaro MRyutaro changed the title feat: 自動保存/復元を起動時(env)+実行時(control/REST)で個別に切り替え可能に feat: 自動保存/復元を起動時(env)で個別に、停止時の自動保存は実行時(REST/control)でも切替可能に Jun 18, 2026
@MRyutaro
MRyutaro merged commit d7049b8 into main Jun 18, 2026
7 checks passed
@MRyutaro
MRyutaro deleted the feat/toggle-auto-checkpoint branch June 18, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants