コンテキスト方式
コンテキスト(context)とは文脈のこと
何が問題か?
複数箇所から更新をされると不整合になりやすい。
不整合を防ごうとすると複数箇所からアクセスされるのでロックが必要。しかし、このロックがパフォーマンスを低下させる。
しかし、「グローバル的な状態」を関数内部まで引き継ぎたい。
各種出力先の切り替え
現在のロケール、言語など
スレッドローカルストレージはスレッドに依存するが、継続方式のようにスレッドが差し替わるようなケースでは使えない。
複数の状態を引き継ぐために複数の引数が必要とすると、すぐに破綻する。
引き継ぐ関数がすべての状態の内容を知っていなければならない。
解決策
本当に扱いたいのは「グローバル」情報でも「スレッド」情報でもなく、「コンテキスト」情報である。
コンテキストオブジェクト(あるいはそのアクセスのためのキー)を作って、関数に引き継ぐ。
コンテキストオブジェクトを引き継ぐ関数は具体的な中味を知らなくてもよい。
コンテキストオブジェクトには任意のタイミングで情報を追加・変更・削除できる必要がある。
コンテキストオブジェクトは基本的には単一スレッドからしかアクセスされないのでロックは不要。
原則として途中で更新するような使い方は望ましくない。その場合は別のオブジェクトとして分離すべき。コンテキストではその分離されたオブジェクトを示すのみとする。
基本的に辞書的なアクセス方式(Key-Value Store)になる。
fork のようにプロセスまたはスレッドが分離する場合は、コピーするなどして分けて管理する。
問題
実質的にグローバル変数の問題を抱えてしまう。
いつどこで変更されたのか分からなくなってしまう。