ものがたり(旧)

atsushieno.hatenablog.com に続く

WCF question (1)ServiceThrottlingBehaviorを正しく実装するにはどうすればいい?

WCFはホント分からないことだらけで、実装していて少なからず困ることがあるので、クイズみたいなかたちにして、ダメ元で答えを募集してみようかなあと思います。って、ただ質問するだけじゃつまらないというかここに書くようなことじゃないから、いろいろ付加情報を書いてみようと思う。

ちなみに、System.ServiceModel.dllの外で、つまりWCFの内部をいじれるような特権的な立場にない状態で、っていう条件も追加しておきましょう。そうすると答えは出ないかもしれないんだけどね。

まずはライトなところから表題の質問です。ServiceThrottlingBehaviorが行うべきことは、ServiceHostBaseの仕組みを分かっていればとても簡単。この前書いたとおり、サービスサイドでリクエスト受付処理を担当しているのはServiceHostBaseとChannelDispatcherで、このChannelDispatcherにServiceThrottleというそのまんまのプロパティが存在するので、ServiceThrottlingBehaviorの各プロパティをもとに、ServiceThrottleのインスタンスを生成して渡してやるだけ。今ある実装がそうなっている。

で、これが何でダメなのかというと、IServiceBehaviorを実装する他のservice behaviorやendpoint behaviorの中には、ServiceHostBaseに新しくChannelDispatcherを追加するものがあるのだけど(前回書いたばかりなのでここでは繰り返さない)、それらのservice behaviorより先にServiceThrottlingBehavior.ApplyDispatchBehavior()が呼び出されてしまったら、後で追加されたChannelDispatcherのServiceThrottleを調整することは出来ないためだ。

ServiceThrottleを設定するのは、ChannelDispatcherがOpenになってしまうと、もう認められない。なのでCommunicationObjectであるところのServiceHostBaseにOpenedイベントにハンドラを追加しても、正しい状態で処理されることは無い。そしてChannelDispatcherはOpeningイベントが呼び出される時点ではまだ存在しない。

そんなわけで、割とお手上げです。どうでしょう、この謎が解ける人いますかねー