言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

Croquet P2P テスト挫折

締め切りに追われる毎日メモ。Croquet のネットワークに関する問題として、試験がやりにくいという事が考えられる。特に、ネットの試験をしたいだけなのに三次元の画面を立ち上げる必要があり大変面倒臭い。そこで、色々工夫したテストフレームワークを作って単体テストを試みるわけだが、かなり限定されたテストしか出来ない事を再確認した。

Croquet の共有のキモは、TeaHost オブジェクトに存在する mapNameToObj 辞書だ。Croquet 同士が通信する場合、この辞書に登録してあるオブジェクトに関してはシリアライズせず、名前がそのオブジェクトの代わりに送られる。TObject に属するもの、すなわち全ての三次元モデルが対象になる(一方で、TObject に属さない数字や文字列、その他の物は単純にシリアライズされる)。

問題は、この辞書へのアクセスがグローバル変数経由であるという事。だからイメージに二つの TeaHost インスタンスを作って試験として通信させる事が出来ない。通信させたとしても、その影響がグローバル変数に登録されてある側の TeaHost に限られるため、あるメッセージが影響されたかどうかを確かめるすべは無い。

これを回避する方法はいろいろ考えられる。グローバル変数を使う代わりの何かが必要なのだが、責任を持つ TeaHost への参照を持たないオブジェクトが殆どなので、実行コンテキストを使うのが最も手軽そうだ。例えば例外を使って呼び出し元の情報を与える事が出来るし、なんとプロセス自体にもプロパティを与える事が出来る。これらの解決方法は、いわゆる動的スコープ(Perl でいう所の local)と同じ効果を持つ。

プロセスのプロパティは、実際にメッセージが「どこから」来たのかという情報を保存するため使われている(ScriptProcess>>hostName)。mapNameToObj 辞書問題は、これに「どこで」実行されるべきかという情報が分かれば解決可能なのだが、非同期実行とグローバル変数のせいで巧妙に隠蔽されてしまう。結局、すぐに解決するのが難しいという事だけが分かった。