Open5
Screeps OS構想
経緯
前バージョンのOSはProcess管理と標準入出力が主な機能で、構造面がふんわりしていたり実質的なDriverである機能の仕様がなかったりOSが担うべきCPU時間管理が行われていなかったりした
今バージョンで達成すること
- 階層ごとの機能と責任範囲の明確化
- 今後のバージョンアップのしやすさ
- 責務をインターフェースで分離
- 個別の機能を更新できるようにする
- [optional] botの実装しやすさ
- 資源の仮想化
構造
プラットフォームの上にOSが載ってその上にbotが載っている
botはDriver群とその上に乗るProcessから成る
OS
OSはプラットフォーム(Screeps)アーキテクチャから独立して稼働するのが理想だが、OSの役割にScreepsアーキテクチャの管理が入っているため完全には独立していない
固有の構造である同期実行・離散時間、CPU時間管理、Memory使用量管理がOSに組み込まれている
またTypeScriptによる実装上の制約がある
SystemCall
OS機能をProcess, Driver, 他のSystemCallから利用するための関数
Botから独立して動作する
DriverFamily
実オブジェクトの仮想化とBotの認知を司る
Botの仕組みに依存して必要な仮想化手法が変わるため、DriverFamilyという単位でまとめて管理する
Process
処理をまとめた単位
階層構造をもつ
大抵は特定のDriverFamilyの存在を前提にする
Process間通信
- 親子間
- 共有メモリ
- 同じ木のProcessの間でインスタンスを共有する
- メソッド呼び出し
- 親Processが子Processのメソッドを呼び出す
- 引数
- 親Processが子Processの実行時に引数を渡す
- 共有メモリ
- 任意の対象
- メッセージング
- Process IDを使用し、OSを介して文字列のメッセージを渡す
- メッセージング
Processの種類
- Application Process
- 最上位Process
- 他のProcessと機能上の差異はない
- 一般的なProcess
Discussion
- CPU時間やMemoryなどはOSが管理する、ということは複数のOSを同時に起動することはできない
- →実世界のマイグレーションなどでは旧OSのブリッジをするなどの対応が必要
Discussion-Process構造化
インターフェースの型付け
- Process間通信
- Processの親子関係
のそれぞれにおいて、 - 引数と返り値のフォーマット
- それをTypeScriptの型システム上に構築できるか
Process実行時間管理
- → 別Processのメソッドを直接呼び出すと、呼び出し元Processの処理時間で処理される
- → それは許容しても良いのでは
Process階層化
-
RoomResource
などを引数に取るProcessは木構造の依存関係をもつ- これはそのようにする
- 親から子へ実行していく形式ではProcessManagerが引数を引き継いでいくのが難しい
- 共有メモリ領域と依存関係で構築すれば、メモリ領域のinterfaceは複数のProcessから必要なinterfaceで解釈して利用できる
- 誰が作成するのか
- どのように依存させるのか
- 一方でその構造に水平に情報処理を行いたい処理もある
- 戦時のリソースのリアロケーションなど
- プリミティブでドメインに依らない処理に分解した上でSystemCall化し、t=0でリクエストを出しt=1で結果を取得するようにする
Process管理
- Process間通信、共有メモリ
- Driverに相当する機能を提供するProcess
- → インターフェースをどこかに公開しておく必要がある
- Processからどのようにnull guardなしでアクセスするか
- Process実行時に与えられる引数は、コマンド入力時には存在しないため使えない
- この用途でのDriverは動的に実行するため、Processとしての性格がある
- → インターフェースをどこかに公開しておく必要がある
- Driverに相当する機能を提供するProcess
- tickごとにProcessインスタンスを作成し、終了時に削除することで型付けと両立できるのではないか
[Discussion] SystemCallとDriverの呼び出し
- ProcessからSystemCallとDriverの機能をどのように呼び出すか
- Driverがそのランタイムに入っていない場合にそのDriverに依存したProcess, そしてそのProcessに依存したProcessが起動しないようにする仕組み(a)
- それをTypeScriptの型システム上に構築できるか
- Driverがそのランタイムに入っていない場合にそのDriverに依存したProcess, そしてそのProcessに依存したProcessが起動しないようにする仕組み(a)
- Process-ProcessManager-SystemCallの循環参照をどのように切るか
要件
- Driver依存の有無は静的にチェックしたい
- Driverの差異はデプロイサーバーの差異
- → 今までサーバー判定に依存していた部分はDriver依存に変わり、直接的にサーバーを参照することは無くす
(a) Processの追加処理
Driverがそのランタイムに入っていない場合にそのDriverに依存したProcess, そしてそのProcessに依存したProcessが起動しないようにする仕組み
- パーソナルコンピュータのOSと同様に、DriverやProcessはOS起動時には読み込まず、インストール処理を経たもののみが動作するようにする
- → OS実行以前に評価されるTSの型システムを使えない
- ランタイム(利用するDriver群)ごとにbranchを切り替える
- → 最終的に統合できないと共通化処理の切り出しなどが手間
- 全Driverが使えるが、必要なDriverが入っていない場合はProcessを起動できないようにする
- → 静的にDriver群が有効かどうか判定する方法はあるのか?起動する段になって利用できないDriverの依存が発見されるようなことはないのか?
- サーバーに起因する差異なのであれば、ランタイムのチェックのみでも良いか?
- 複数のDriver(サーバー)に依存しないことのチェックはできるか
Process<DriverFamily | void>
- 複数のDriver(サーバー)に依存しないことのチェックはできるか
構成
- Bootloader
- Kernel
- SystemCall
- Driver
- ProcessManager
- Process
- Kernel