JZOSのWLM API
こういうのが出てたのは知っていたよ。
今日たまたま気になったので少し見てみた。
IBM: JZOS Java Launcher and Toolkit Overview
WAS for z/OS V8.0なら使えるけれども、
このAPIをWAS上で使うことは無い。使ってはいけない。
EnclaveとThreadには関係がある。
J2EE環境でThreadを自ら作ることはご法度だから、使うことは絶対にないし、
WAS for z/OSにはwlm_classification_fileがあるわけだから、そもそも使う必要がない。
どうやらWLM APIのサンプルは無いようだ。
PDFにも何の説明もないじゃないか。
ざっと見た感じ、このAPIでWLMの一部のサービスが使えるようになる。
z/OSのXL C/C++にはWLM関連のAPIが用意されているので、
それらを軽くWrapして提供しているという内容だ。
このAPIで何が変わるかを考えてみた。
あまりそのへん詳しくないが、
ACCOUNTING情報で課金するようなタイプのものに向いている。
これまでだったらJCLに埋め込んだりとかして、
JCLが大量になるみたいなことから解放されるんだと思う。
また、WASの使ってるモデルだと、
Servantは1つのService Classのみになるが、
これの場合は全てのThreadを違うService Classで動かせるのではにないかと思う。
それはすこぶる面白い。
データに基づいて、動的にService Classを振り分けられる。
きっと、その部分についてはWASよりも強力なのだ。
WASでは事前設定になる。設定は動的にも変更は可能ではある。
しかしHTTPとかのURLベースの変更は動的な設定変更でもいいが、
EJBなどはejb-jar.xmlとかに手を加えることになるため、
意外とお手軽に変えられるというものでもない。
では、この場で使い方を書くのは少々つらいが、イメージを書いてみる。
まずはWLMに接続しないといけない。
WorkloadManger wlm = new WorkloadManager("subSystemType","subSystemName");
JZOS作ってる人はコンストラクタで何かやるのが好きらしい。
私はそういうのは嫌いだ。
subSystemTypeは、WASならCBが使われているので、
独自のサブシステム名を作るということか!?
4文字以内のサブシステム名を作る。
subSystemNameは8文字のものになる。
この情報はIWMWMCON (31bit) / IWM4CON (64bit)に渡すために使われる。
C/C++とか言いながらアセンブラのこと書いたら意味ないな。
C/C++ならば ConnectWorkMgr() — Connect to WLM as a work manager
というファンクションを使ってるはずだ。
次にやることはきっとコネクショントークンを取得すること。
int connToken = wlm.getConnToken();
if(connToken == 0){
// not connected. throw Exception.
}
ServerClassification sc = null;
try{
sc = wlm.createServerClassification();
}catch(ErrnoException e){
// error processing.
}
ServerClassificationはWorkUnitを作るのに使う。
また、あとでdestroyServerClassificationしないといけない。
ここからServerClassificationのインスタンスに色々設定していく。
setClassifyInt(int,int)
setClassifyString(int,String)
この二つは汎用的なメソッドだけど、
間違いを避けるために使わない方がいいだろう。
それにしても、全てのsetterからErrnoExceptionが飛んでくるのがうざい。
このあたりはJavaDocの上部に書いてあるように、
__server_classifyCreate
__server_classify
__server_classifyDestroy
これらのC/C++ Library APIを呼び出すことになる。
アセンブラならIWMCLSFYあたり。
若干、異色なのsetterが混じってると思ったが、
どうやらちゃんとしたものらしい。それは知らなかった。
次に、WorkUnitを生成する。
コンストラクタが3つ用意されているが、
ServerClassificationを使えるのは2つ。
ArrivalTimeを設定したい人はZUtil.getTodClock()を使う。
functionNameって何だろう。
これは知らんかった。なんのために必要なんだ・・・。
とりあえず、後で渡すRunnableの役割に応じて名前を渡す。
ここでは次のC/C++ファンクションを呼び出すことになる。
CreateWorkUnit() — Create WLM work unit
WorkUnit wu = new WorkUnit(sc,"func name");
別途用意したRunnable実装クラスのインスタンスを渡す。
try{
wu.run( new MyRunnable());
}catch(ErrnoException e){
}
まあ、これはダメな例。
このやり方ではスレッド作ってないからほとんど意味がないんだ。
wrapを使って組んだ方がエレガントになる。
そして、ExecutorService等を使うことになるだろう。
Runnable myWork = wu.wrap(nw MyRunnable());
ExecutorService es = Executors.newCachedThreadPool()
Future<?> result = es.submit(myWork);
ここではWLM APIが関心事なんで、
結果が欲しいだとか、ExecutorServiceのきちんとした使い方は省きます。
さてと、run()の中では、join()とleave()が動きます。
C/C++ではこれらに対応。
JoinWorkUnit() — Join a WLM work unit
LeaveWorkUnit() — Leave a WLM work unit
アセンブラならこれら。
IWMEJOIN – Joining a WLM Enclave
IWMELEAV – Leaving an Enclave
AMODE31のしか見つからない点が不安要素だ。
あとは、WorkUnitをdeleteする。
wu.delete();
DeleteWorkUnit() — Delete a WLM work unit
IWMEDELE – Delete an Enclave
deleteは必須なので、finallyでやらないといけないな。
その後にServerClassificationをdestroyする。
wlm.destroyServerClassification(sc);
このdestroyは、ServerClassificationをcreateしたスレッドと同じでないといけない。
そうC/C++のマニュアルには書いてある。
おそらく、WorkUnitを作った後ならすぐdestroyして良いと思う。
最後にWLMからdisconnectする。
wlm.disconnect();
これもfinallyで書くべき。
RACF系のことが全然書けてないや。
BPX.WLMSERVERとかは必要。
最低でもこれらのマニュアルは必読。
XL C/C++ Run-Time Library Reference
MVS Programming: Workload Management Services
MVS Planning Workload Management
ErrnoExceptionはC/C++のを見ないといけないだろう。
JDBCでDB2に繋ぐなどした時に、それらもEnclaveにカウントされるかも??
WASの場合はそうだけどJZOSでやるとどうなるかな。
まあ、自分が使うことはないからこのへんにしておこう。