OxideTerm ノードセッション所有権 は何をしますか?
このスキルは、変更がリモートセッションやバックグラウンドジョブを作成、共有、クローズ、再接続、または監視するコンポーネントを変更する可能性がある場合に使用します。
コア不変条件
接続されたSSHノードは、それを消費するターミナルペインから独立しています。UIのライフタイムがバックエンドのライフタイムを暗黙的に決定してはなりません。
flowchart TD
W["ワークスペースまたはアプリケーションのライフタイム"] --> R["NodeRouter と接続レジストリ"]
R --> N["物理SSHノード接続"]
N --> T["ターミナルコンシューマ"]
N --> S["SFTPコンシューマ"]
N --> F["フォワーディングコンシューマ"]
R --> H["ヘルスチェックと再接続ジョブ"]
必須ルール
- ノードの活性は接続レジストリ、
NodeRouter、または明示的なノード切断操作に属します。 - ターミナルペインを閉じると、そのターミナルコンシューマが削除されます。共有ノードを切断してはなりません。
- SFTPは、実際のノードによってバックアップされたSFTPセッションを取得する必要があります。ファイル転送を模倣するシェルコマンドは、文書化された互換性フォールバックとしてのみ許可されます。
- ポートフォワーディングは、自身のリスナーとブリッジタスクを所有します。これらのタスクは、ターミナルペインが開いていなくても存続し、フォワーディングルールまたは所有するノードが停止したときに停止する必要があります。
- 再接続、ヘルスチェック、グレース期間、子プロセスブリッジには、ノード、ワークスペース、またはアプリケーションのライフタイムに結びついた明示的な所有者とキャンセルパスが必要です。
- 長時間実行される作業は、コマンドハンドラが戻ったときにドロップされるワンショットランタイム上で実行してはなりません。
- ジャンプホストを介して接続された子ノードは、子トランスポートが必要とする間、親接続を保持する必要があります。
- UIコンポーネントは、ルーターまたはレジストリのイベントを通じてランタイム状態を監視します。ターミナルの存在からノードの活性を推測してはなりません。
- 所有権の移行(作成、共有、無効化、再取得、キャンセル、UI破棄後の意図的な存続)には、簡潔な英語のコメントを追加してください。
禁止される回避策
- ノードバックアップのAPIが不便だからといって、管理されていない2番目のSSHトランスポートを開かないでください。
- ホストに関連付けられた最初のターミナルペインを選択して接続を見つけないでください。
- 長時間実行されるタスクを一時的なダイアログ、コマンドハンドラ、またはターミナルビューにのみ保存しないでください。
- 1つのチャネル、ペイン、SFTPリクエスト、またはフォワーディングコンシューマが閉じただけで、ノードを切断済みとマークしないでください。
- 生成された子プロセスやTokioタスクを、シャットダウンシグナルと制限付き完了パスなしで切り離したままにしないでください。
推奨プラクティス
- バックエンドの依存関係をそれぞれ、偶発的な
Arcの保持に依存するのではなく、レジストリ内のコンシューマまたは所有者として表現します。 - 物理トランスポートの状態は接続エントリに保持し、論理トポロジは
NodeRouterに保持します。 - 切断カスケードは、ホスト文字列を照合するのではなく、記録された親子接続IDに従うようにします。
- タスクハンドルまたはキャンセル送信側は、そのライフタイムがジョブを定義するオブジェクトに保持します。
- ターミナル状態のポーリングよりも、イベント駆動型のUI更新を優先します。
互換性パス
互換性フォールバックは、明示的で、制限付きで、正確に報告される場合にのみ許可されます。それらをネイティブのSFTP、フォワーディング、またはノードセッション実装として説明してはなりません。一時的なフォールバックであっても、所有者とクリーンアップパスを記録してください。
例
不正:
// ペインを閉じると、共有ノードの唯一の所有者が誤って破棄される。
struct TerminalPane {
ssh_transport: SshTransport,
}
正しい形:
// ペインは自身のコンシューマ登録のみを所有し、レジストリがトランスポートの活性を所有する。
struct TerminalPane {
connection_id: String,
terminal_consumer: ConnectionConsumer,
}
不正:
tokio::runtime::Runtime::new()?.spawn(run_forward_listener());
// ランタイムはコマンドが戻ったときにドロップされる。
正しい形:
// フォワーディング所有者は、キャンセルハンドルと完了ハンドルの両方を保持する。
struct ForwardingJob {
shutdown_tx: Option<oneshot::Sender<()>>,
worker: JoinHandle<()>,
}
レビューチェックリスト
- 物理接続の所有者を特定します。
- すべてのターミナル、SFTP、フォワーディング、再接続、ヘルスチェック、子ノードコンシューマをリストアップします。
- 1つのコンシューマを閉じても、関連しないコンシューマが閉じないことを確認します。
- 明示的なノード切断が、依存するジョブと子トランスポートを停止することを確認します。
- 生成されたすべてのタスクまたはプロセスについて、保持されている所有者、キャンセルシグナル、およびクリーンアップパスを検査します。
- UI状態が、ターミナルから派生した活性ではなく、ノードイベントを消費することを確認します。
- 残っている互換性フォールバックを正確に記述します。
検証
- 最後のターミナルを閉じ、他の登録されたコンシューマがノードを使用できるままであることを確認します。
- ターミナルペインを必要とせずにSFTPを開きます。
- ローカル、リモート、動的フォワーディングを開始し、リスナーがペインクローズ後も生き残ることを確認します。
- 親ノードを切断し、依存する子ノードとジョブが一貫して遷移することを確認します。
- グレース期間内に再接続し、関連しないUI状態が失われないことを確認します。
- タスク/プロセスのクリーンアップが、明示的な切断後およびアプリケーションシャットダウン後に完了することを確認します。