抑制
柔軟で可変性に富んだスケーラビリティの高い環境を自由に持てることは重要ですが、特定のリソースにいつも最高速度でアクセスしなければならないわけでもありません。サービス、ライブラリ、データソースなどを利用するとき、運用上の制限や法的制限を受けることがあります。
例えば、商用エンティティ抽出プログラムの中には実際、厄介なライセンス条項が付随するものがあります。一度に使用できるスレッド数が1つに制限されていて、それを超える数のスレッドを使用した場合に何万ドルも支払わなければならないというようなものです(これはCPU単位のライセンスの極端な例ですが)。CPUの余った能力をシステムの他の部分のために利用しようとすると、たちまち弁護士から、それは該当しないと告げられることになります!
例えば、Results r = ExpensiveTool.extractEntity(myDocument);というAPIを使って必要な機能にアクセスできるものとします。ここでの目標は、単一のスレッドにアクセスを制限することです。Javaのスレッド処理について知っていれば、次のようなことを行いたくなるでしょう。
Results r = null;
synchronized(someLock) {
r = ExpensiveTool.extractEntity(myDocument);
}
これで法的問題はクリアされますが、この状況でコードレベルのモニタを使用するのは、いかにも雑です。ビジネス上の理由から余計に支払う価値があると判断した場合、単一スレッドの使用を強制する状態から2個ないし3個のスレッドを使用する状態に簡単に移行できません。Javaモニタはミューテックス(相互排他ロック)に過ぎないからです。ロック機構を、セマフォをカウントする方式(JDK 5以降のjava.util.concurrent.Semaphoreを参照)か、もっと高度なツールに変更する必要があります。さらに、スレッドの使用制限ポリシーを各種のリソース、ツール、システムなどに適用しようと考えると、話はたちまち複雑になります。
NetKernelのURIによる抽象化と抑制の機構は、この状況でも有効です。最初に、ライセンス費用のかかる問題のツールをactive:expensive-toolというようなURIの背後に置きます。これを直接呼び出す代わりに、要求を呼び出しでラップして、設定ファイルに基づき要求を抑制できるようにします。
req=context.createSubRequest("active:throttle");
req.addArgument("id","throttle:expensive-tool");
req.addArgument("configuration", "ffcpl:/etc/MyThrottleConfig.xml");
req.addArgument("uri","active:expensive-tool");
req.addArgument("doc", "http://somedocument.com");
handle = context.issueAsyncSubRequest(req);
result = handle.join();
この設定ファイルは、該当するURIに関してカーネルに同時に投入できる要求の個数と、要求の拒否が開始されるまでの間に待ち行列に入れることができる要求の個数を示します。
<throttle> <concurrency>1</concurrency> <queue>10</queue> </throttle>
こうすれば、法的問題をクリアしつつ、第2または第3のライセンスを購入する場合に、ポリシーを変更しないで、設定ファイルを変更するだけで済みます。そうすることに意味があるなら、他のリソースに対する要求も同じ抑制の定義でラップできます。任意のツールやサービスに対して、その機能がどのような方法で提供されていても簡単に抑制を実施できる点で、この方法は非常に優れています! これを言語レベルの並列性の構造で扱えないわけではありません。それよりも、一般化が難しく、細部が重視され、理解に手間がかかることが問題とされます。
並行スレッド処理は便利だが、微妙
Javaの並行スレッド処理構造のサポートは非常に便利ですが、まだ微妙で、エラーを免れない面があります。言語レベルのマルチスレッド処理ツールは、多くの場合、任意の処理動作が複雑なシステムの連携動作と組み合わされる場合や、ビジネスルールが変更される場合に、適切に抽象化されないことがあります。発想をNetKernelの提供するリソース指向の方法に切り替えることで、既存のコードの多くを再利用しつつ、最新のハードウェアやCPUの能力を余すことなく利用することが可能となります。NetKernelのような環境では言語の並列性ツールが有効に活用されるため、自分でツールを用意しなくてもかまいません。重い処理はこれに任せてみてはどうでしょう!
