プロンプトとコンテキスト
ランタイム、テナント分離、実行バジェットはすでに存在しています。問題はより限定的です。インストールされた数百のコンポーネントが複数世代のWebAssembly Interface Types(WIT)を実装しており、ワークフローによってパーサー、リダクター、エクスポーターが合成される場合があります。プラットフォームがコントラクトを安全に変更できるようにする互換性および合成レイヤーを設計してください。
WITは動作そのものではなくコントラクトを定義します。worldはコンポーネントが何をインポートおよびエクスポートするかを列挙し、Component Modelによってコンポーネントの合成が可能になります。これらにより互換性のテストが可能になりますが、どの変更が安全であるか、あるいは合成グラフがどのケーパビリティを受け取るべきかを決定するわけではありません。プラットフォームがそのポリシーを提供する必要があります。
面接官が評価するポイント
- ソース言語の互換性、WITの構造的(shape)互換性、および振る舞いの互換性を区別しているか。
- 最終的なコンポーネントグラフ内のすべてのインポートが、偶発的に継承されるのではなく、明示的に認可されているか。
- アダプターが永続的な隠蔽ロジックになるのではなく、バージョン管理され、観測可能で、削除可能になっているか。
- ロールバック時に、以前のコンポーネントが期待していたデータおよびリソースのセマンティクスが維持されるか。
確認すべき明確化のための質問
- インストールされているどのインターフェース世代を、どのくらいの期間実行可能な状態にしておく必要があるか?
- 呼び出しはステートレスな値、所有(owned)または借用(borrowed)されたリソース、ストリーム、あるいは長期間有効なハンドルのいずれであるか?
- プラグインは別のプラグインを直接呼び出すことができるか、それともすべての呼び出しがホストを経由する必要があるか?
- どの変更が加法的(additive)であり、どの変更が意味、エラー、または所有権を変更するか?
- ワークフローはアトミックにロールバックする必要があるか、それともコンポーネントが異なるバージョンを使用してもよいか?
ステートレスな値のアダプターは多くの場合インラインで実行できますが、リソースの所有権の変更には新しいメジャーコントラクトと移行が必要になる場合があります。直接合成が許容されるのは、最終的なインポートがテナントの付与範囲内に収まっていることをリンカーが証明できる場合に限られます。
30秒の回答
「すべてのWITパッケージとworldを不変のバージョンで登録し、そのインポート、エクスポート、型、およびリソースの所有権を計算した上で、インスタンス化の前に提案されたグラフを検証します。既存のプラグインは古いコントラクトを維持します。小さな明示的なアダプターが古い値を新しいインターフェースに変換できますが、ケーパビリティを勝手に作成したり、障害セマンティクスを暗黙的に変更したりすることはできません。ホストはテナントポリシーと最終グラフで宣言されたインポートの積集合のみを付与します。記録されたフィクスチャ上で両方のバージョンを比較し、テナントごとにカナリアリリースを行い、ロールバックおよび廃止の基準を満たすまで古いグラフを維持します。」
ステップごとの詳細解説
1. インターフェースレジストリと互換性レポートの構築
WITパッケージバージョン、world、インポート、エクスポート、型定義、所有権ルール、アーティファクトダイジェスト、およびアダプターチェーンを保存します。公開時に、新しいコントラクトをサポートされているすべての先行バージョンと比較します。オプショナルなフィールドの追加は適応可能な場合がありますが、バリアントケースの削除、エラーの意味の変更、借用ハンドルの所有リソースへの変更には、明示的な移行の決定が必要です。
2. アダプターを限定的かつ単一方向に保つ
アダプターは、ある既知のコントラクトを別のコントラクトに変換します。フィールドの名前を変更したり、文書化されたデフォルト値を提供したり、古いエラーを新しいバリアントにマッピングしたりできます。安全に表現できない情報は拒否しなければなりません。可能な限りアダプターチェーンをサポート対象の1ホップに制限してください。長いチェーンは曖昧さを増大させ、ロールバックの推論を困難にします。
3. 合成グラフの認可
リンクを行う前に、すべてのインポートをプロバイダーに解決し、最終的なケーパビリティマニフェストを生成します。ホストは、ファイルシステム、ネットワーク、クロック、乱数、またはビジネスサービスの各インポートを、テナントおよびプラグインの付与権限と照合してチェックします。ネットワークアクセスをインポートしないリダクターが、エクスポーターと合成されたというだけでそのアクセス権を取得してはなりません。特権を要する呼び出しはホスト所有のインターフェースを経由させ、ポリシーと監査を単一の境界に維持します。
4. コントラクトを廃止する前の振る舞いの証明
決定論的なフィクスチャ上で古いグラフと新しいグラフを実行します。型付けされた出力、宣言されたエラー、リソースの作成と解放、ホスト呼び出し、および有界なパフォーマンスを比較します。入力を安全に処理できる場合にのみ実際のリクエストをシャドーイングし、テナントごとにカナリアリリースを行います。ロールバックではグラフ記述子を最後の互換性のあるアーティファクトに切り替えます。ステートフルなリソースでは、単純なポインタ切り替えではなく、移行またはドレイン(排出)が必要です。
優れた回答例
「私はWIT worldをデプロイ可能なコントラクトとして扱います。不変の各レジストリエントリには、パッケージバージョン、world、完全なインポート/エクスポートセット、型の形状、リソースの所有権、アーティファクトダイジェスト、およびサポート対象の先行バージョンが記録されます。値のみの加法的な変更にはレビュー済みのアダプターを1つ使用できますが、所有権の変更、バリアントケースの欠落、または新しい副作用には、新しいコントラクトと明示的なコンシューマー移行が必要です。
合成はグラフ記述子から行われます。リンカーがプロバイダーを解決しますが、ホストはグラフの完全なインポートセットを個別に認可します。ケーパビリティは、テナントポリシーと各コンポーネントの宣言された付与権限によって制限されます。ロールアウトのために、両方のグラフでフィクスチャを再生し、値、エラー、ホスト呼び出し、リソースのライフサイクルを比較します。その後、テナントごとにカナリアリリースを実施し、不一致、エラー、レイテンシ、リークのしきい値をクリアするまで以前のグラフを保持します。これにより、Wasmサンドボックス構築の一般的な問題ではなく、インターフェースの進化と安全な合成という課題に対応します。」
よくある間違い
- すべての加法的な変更を互換性があるとみなす → 新たに必須となったインポートや変更されたデフォルト値は動作を変滅させる可能性がある → 型、ケーパビリティ、所有権、およびセマンティクスの変更を個別に分類する。
- 合成時にすべてのインポートを単純に統合(union)する → 低権限コンポーネントが別のコンポーネントの権限を取得してしまう → 解決されたグラフを明示的な付与権限に対して認可する。
- アダプターを無制限に積み重ねる → 動作が不透明なチェーンに依存してしまう → 有界なホップ数のみをサポートし、使用状況のエビデンスに基づいてアダプターを廃止する。
- 成功時の出力のみを比較する → エラー、ホスト呼び出し、リソースリークが劣化する可能性がある → 失敗、副作用、所有権、およびバジェットを比較する。
- ステートフルなコンポーネントを即座にロールバックする → アクティブなハンドルが新しいコントラクトに属している可能性がある → 切り替え前にセッションをドレイン、移行、または固定する。
フォローアップの質問と回答
新たに必須となったケーパビリティはどのように処理しますか?
パーミッションの変更として扱います。新しいグラフを公開し、要求されたケーパビリティをテナント管理者に提示し、明示的な付与が行われた後にのみアクティブ化します。既存のインストールは古いコントラクトのまま維持されます。
古い値が新しい型で表現できない場合はどうしますか?
アダプターは型付けされた非互換性エラーを返し、影響を受けるフィクスチャまたはテナントに対するロールアウトはブロックされます。デフォルト値を勝手に作成するとデータ損失が隠蔽されてしまいます。移行ツールまたは並行メジャーバージョンを使用します。
アダプターはどのように廃止しますか?
インストールされている呼び出し元、実際の呼び出し、不一致率、最終使用日時をバージョンごとに追跡します。まず新規インストールを停止し、呼び出し元を移行させ、ロールバック期間を設けた上で、サポート対象のグラフから参照されなくなった時点でアダプターを削除します。
コンポーネントはホストを介さずに相互に呼び出すことができますか?
解決されたインポートとリソースセマンティクスが既知であれば静的に合成可能ですが、特権操作は依然としてホスト提供のインターフェースを経由します。認可、クォータ、および監査は制御された単一の境界に留まります。