CWSANDBOX_API_KEY に設定した CoreWeave API アクセストークンを使用します。Forge のAPIキーによる認証については、はじめにを参照してください。CKS の要件については、配置モードを参照してください。
このガイドでは、サンドボックスが作成からシャットダウンまでどのように進行するか、通過する状態、開始と待機の方法、およびクリーンに停止する方法について説明します。作成パターンの選択、起動タイミングの制御、またはSDKコードでの信頼性の高いシャットダウンの処理が必要な場合に、このガイドを使用してください。
ライフサイクルの状態
各サンドボックスは、起動、実行、シャットダウンの過程で一連の状態を経ます。SDK では、これらをSandboxStatus 値として表します。
PENDING と CREATING は一時的な状態です。SDK はこれらの状態の間、自動的にポーリングを継続します。
TERMINATING はバックエンドの一時的な状態であり、wait_until_complete() と stop().result()
によって終端状態まで進められます。RUNNING は安定した稼働状態です。
COMPLETED と FAILED は終端状態です。UNSPECIFIED は、ポーリング時に SDK によって
COMPLETED にマッピングされます。
作成パターン
サンドボックスの作成方法は 2 つあり、起動 RPC が実行されるタイミングが異なります。以下のセクションでは、各パターンとその使い分けについて説明します。Sandbox.run(): 即時開始
Sandbox.run() はサンドボックスを作成したうえで内部的に start().result() を呼び出し、バックエンドがリクエストを受け入れるまでブロックします。
session.sandbox(): 遅延起動
session.sandbox() は、ネットワークコールを行わずにサンドボックスオブジェクトを作成します。起動 RPC は
初回使用時に発火します:
メインコマンドの有効期間
run() または session.sandbox() に渡されるコマンドは、サンドボックスのメインプロセスです。このプロセスが
終了したときの動作は、終了ステータスによって異なります:
- 終了ステータス 0: サンドボックスは
COMPLETEDに遷移します。 - 0 以外の終了ステータス: プラットフォームがメインプロセスのコンテナーを再起動します。すでに
RUNNINGに達しているサンドボックスは 再起動中もRUNNINGのままで、まだ達していないサンドボックスはCREATINGのままです。wait_until_complete()は再起動中も待機を続け、timeoutに達するまで待機します。 - 再起動の上限に到達: メインプロセスが 0 以外のステータスで終了し続けると、
再起動の上限 (現在は 6 回) に達した時点でサンドボックスは
FAILEDに遷移します。
exec() を使用してください。
サンドボックスを起動する
サンドボックス オブジェクトが存在した後、明示的に起動するか、SDK に任せて初回使用時に起動させるかのいずれかを選択できます。以下のセクションでは、両方のアプローチと、コンテキストマネージャーがそれらとどのように相互作用するかについて説明します。明示的な起動
start() は起動 RPC を送信し、OperationRef[None] を返します:
自動起動
ほとんどのオペレーションは、サンドボックスがまだ起動していない場合に自動的に起動します。一般的なケースでは、サンドボックスを作成してすぐに使用を開始できます。コンテキストマネージャーと start
コンテキストマネージャー (with/async with) はエントリ時に start() を呼び出しますが、wait() は呼び出しません。
最初のオペレーションの前にサンドボックスが RUNNING 状態である必要がある場合は、wait() を明示的に呼び出してください:
exec() が内部で RUNNING 状態になるまで待機するため、これが問題になることはほとんどありません。明示的な
wait() は、起動時の失敗とオペレーションの失敗を切り分けたい場合に役立ちます。
サンドボックスを待機する
SDK は、サンドボックスがオペレーションの準備完了になるのを待つか、メインコマンドを終了するのを待つかによって、2 つの待機メソッドを提供します。以下のセクションでは、各メソッドと、起動およびオペレーションのタイムアウトがどのように関連するかを説明します。wait(): RUNNING になるまでブロックする
wait() は、サンドボックスが RUNNING、TERMINATING、または終端状態のいずれかになるまでポーリングします。
wait() はメソッドチェーンのために自身を返します。
wait() は次のように処理します。
wait_until_complete(): 終端状態までブロック
wait_until_complete() は、サンドボックスが終端状態に達するまでブロックし、
TERMINATING の間も自動的にポーリングします。メインコマンドが処理を行うサンドボックスで使用してください:
raise_on_termination パラメーター (デフォルトは True) は、このクライアントが stop() を呼び出した後に
wait_until_complete() が SandboxTerminatedError を送出するかどうかを制御します。
外部からの停止は、個別のエラーなしで COMPLETED として扱われます。これは、バックエンドがまだ
終了理由のメタデータを提供していないためです。一方、最大ライフタイムに達したサンドボックスは
FAILED で終了するため、wait_until_complete() は SandboxFailedError を送出します。
タイムアウトのフェーズ
起動時の待機時間と操作のタイムアウトは別々のフェーズですが、どちらもサンドボックスの最大ライフタイム が上限となります:- 起動待機: RUNNING に到達するまでに PENDING/CREATING 状態で費やされる時間です。
wait()またはwait_until_complete()のtimeoutパラメーターで制御します。バックエンドのスケジューリングによって異なりますが、通常は 30~60 秒です。 - 操作タイムアウト: 個々の exec、read、write にかかる時間です。
exec()のtimeout_seconds、 またはSandboxDefaultsのrequest_timeout_secondsで制御します。起動待機は含まれません。 - 最大ライフタイム: サンドボックスが存在できる合計の実時間で、起動時点から数え、
起動待機も含みます。
max_lifetime_secondsで制御します。設定しない場合、 ランナーポリシーのデフォルトが適用されます。正のデフォルト値が設定されていない場合は、プラットフォームのフォールバック値として 10 分が適用されます。
max_lifetime_seconds は、想定される作業の合計時間を十分に上回る値に設定してください。この値はサンドボックスの起動後に
変更できません。4 つのタイムアウト設定すべてとそれらの関係については、
タイムアウトを参照してください。30 日間の上限と
Serverless および CKS の設定例については、長時間稼働するサンドボックスを実行するを参照してください。
オペレーションとライフサイクル
exec()、read_file()、write_file() などのオペレーションは、必要に応じてサンドボックスを自動的に起動し、
RUNNING になるまで待機してから処理を続行します。
timeout_seconds) は、サンドボックスが RUNNING になってから適用されます。起動にかかる
時間は含まれません。
サンドボックスの停止とサポート終了
このセクションでは、サンドボックスをシャットダウンする方法、停止後の動作、およびstop() と delete() の使い分けについて説明します。
stop()
stop() は停止リクエストを送信し、OperationRef[None] を返します。サンドボックスは
TERMINATING (猶予期間中のドレイン) を経て、終端状態に遷移します。返された
OperationRef は、停止 RPC が成功した時点ではなく、バックエンドが終端状態を
確認した時点で解決されます。
stop() は処理中の起動にも対応しています。起動がまだ処理中の場合は、起動の完了を待ってから停止します。stop() を同時に、または繰り返し呼び出した場合は 1 つの停止オペレーションが共有され、
停止 RPC が重複して発行されることはありません。そのため、stop() を繰り返し呼び出しても安全で、コストもほとんどかかりません。
停止後の動作
stop() が呼び出されると、サンドボックスは TERMINATING (猶予期間中の
ドレイン状態) を経て、終端状態 (COMPLETED または FAILED) に遷移します。stop() が
呼び出された後は、サンドボックスを使用できません。それ以降のオペレーションでは SandboxNotRunningError が発生します。
status プロパティは、最後の呼び出しの結果からキャッシュされます。停止前に最新のデータを取得するには、
get_status() を使用します:
コンテキストマネージャーの終了
コンテキストマネージャーは終了時に自動的にstop() を呼び出します:
stop() と delete() の比較
現在使用しているサンドボックスには
stop() を使用します。Sandbox.list() または Sandbox.from_id() で
見つかったサンドボックスのクリーンアップには delete() を使用します:
Under the hood
SDK は、独自の asyncio イベントループを持つバックグラウンドのデーモンスレッド上で、すべての gRPC オペレーションを実行します。 この設計により、以下が実現されます。- 同期 API (
.result()) は、バックグラウンドのループがネットワークコールを処理している間、 呼び出し元のスレッドをブロックします。 - 非同期 API (
await) は同じバックグラウンドのループに橋渡しされるため、どちらのパターンも同じ 基盤実装を使用します。 - バックグラウンドのループは、初回使用時に遅延起動されます。gRPC チャンネルも同様に遅延作成されます。
- 自動起動は、各オペレーションの前に
sandbox_idが None かどうかを確認し、None の場合はstart()をトリガーする仕組みです。 - プロセス終了時には、クリーンアップハンドラ (atexit + シグナルハンドラ) が登録済みセッション内の すべてのサンドボックスを停止します。クリーンアップ中にもう一度 Ctrl+C を押すと、即座に強制終了します。
nest_asyncio を使用しなくても Jupyter ノートブックで動作します。使用パターンについては、同期 API と非同期 API のパターンを比較するガイド を参照してください。