以下の構文を使用すると、ある InterSystems IRIS システムから別の InterSystems IRIS システムへ、リモート・ジョブを送信できます。
JOB routine[joblocation]
JOB routine|joblocation|
2 つの形式は類似しています。joblocation パラメータを囲むのは、角括弧 ([ ])、または垂直バー ( | ) のどちらでも使用できます。リモート・ジョブは、ルーチン・パラメータ、プロセス・パラメータ、またはタイムアウトを渡すことはできません。
ジョブの場所を指定する構文の形式によって、InterSystems IRIS の動作が異なります。
joblocation 構文 |
結果 |
["namespace"] |
InterSystems IRIS は、この明示的なネームスペースが、ローカル・システムまたはリモート・システムに既定のデータセットを持っているかどうかをチェックします。既定のデータセットがローカル・システムにある場合、システムは指定されたパラメータを使用してジョブを開始します。既定のデータセットがリモート・システムにある場合、システムはネームスペースの既定のデータセットのディレクトリでリモート・ジョブを開始します。 |
["dir","sys"] |
InterSystems IRIS はこの場所を暗黙のネームスペースの形式 ["^sys^dir"] に変換します。 |
["^sys^dir"] |
ジョブは指定されたリモート・システムの指定されたディレクトリ内で実行します。InterSystems IRIS では、ルーチン・パラメータ、プロセス・パラメータ、またはタイムアウト指定は許可されていません。 |
["^^dir"] |
ジョブは現在のシステムのローカル・ジョブとして、指定されたディレクトリ (暗黙のネームスペース) で指定されたパラメータを使用して動作します。暗黙のネームスペースは、"^^dir" のように 2 つのキャレット文字が先行するディレクトリ・パスです。 |
["dir",""] |
<COMMAND> エラーが発行されます。 |
リモート・ジョブでのグローバル・マッピング (Windows)
要求システムでグローバル・マッピングが定義されているかどうかにかかわらず、InterSystems IRIS ではリモート・ジョブに対してグローバル・マッピングは用意されていません。グローバル・マッピングの不足を回避するためには、グローバル指定で、そのネームスペースにないグローバルの場所をポイントする拡張参照を使用してください。拡張参照で指定するネームスペースが、指定するシステムで定義されていない場合、<NAMESPACE> エラーが返されます。ネームスペースと拡張グローバル参照の構文に関する詳細は、"グローバルの使用法" の "グローバル構造" を参照してください。
特殊変数 $ZCHILD と $ZPARENT の使用
$ZPARENT には、現在のプロセスをジョブ化したプロセスの PID (プロセス ID) が含まれます。現在のプロセスが JOB コマンドで作成されなかった場合は、0 が含まれます。
$ZCHILD には、JOB コマンドによって最後に作成されたプロセスの PID が含まれています。このプロセスは成功したものではない場合もあります。
$ZCHILD を使用すると、JOB コマンドを実行する前後の $ZCHILD 値を比較することにより、リモート・ジョブの実行状態を判断することができます。前後の値が異なり、後の値がゼロ以外の場合、後の $ZCHILD 値は、新しく作成されたリモート・ジョブの PID であり、プロセスが正常に作成されたことを示します。後の値がゼロの場合、または後の値が前の値と同じ場合、リモート・ジョブは作成されていません。
$ZCHILD からは、リモート・ジョブが作成されたことのみがわかります。リモート・ジョブが正常に実行されたかどうかはわかりません。リモート・プロセスがエラーなく実行され、完了まで実行されたかどうかを判断する最も良い方法は、実行中のコードにある種のログとエラー・トラップを用意することです。リモート・ジョブ・メカニズムは、リモート・プロセス・エラーやリモート・プロセスの終了、正常に実行されたかどうかなどについて、親プロセスに一切通知しません。
JOB サーバの使用
JOB サーバは、JOB 要求の処理を待つ InterSystems IRIS プロセスです。JOB サーバに付属しているジョブ起動プロセスは、新しいプロセスを作成する必要があるというオーバーヘッドの付加を回避します。使用可能な場合、JOB サーバを使用するように設定された switch パラメータで JOB コマンドが発行されるたびに、InterSystems IRIS は、これに対処できる JOB サーバがあるかどうかをチェックします。JOB サーバがない場合は、Caché がプロセスを作成します。使用できる JOB サーバがある場合、JOB はその JOB サーバに付属します。
JOB サーバで実行されている JOB で HALT が実行された場合、JOB サーバは他の JOB 要求を受け取るまで、ハイバネーション状態になります。JOB サーバで動作していないジョブ起動プロセスは終了し、そのプロセスは削除されます。
JOB サーバ環境と、ジョブ起動プロセス環境では回避できない相違点がいくつかあります。ジョブ起動プロセスを JOB サーバで実行する場合に、これらがセキュリティ上の問題になる可能性があります。ジョブ起動プロセスは、InterSystems IRIS レベルで JOB コマンドを発行したプロセスのセキュリティ属性を受け付けます。
入出力デバイス
一度に 1 つのプロセスだけが、デバイスを所有できます。これは、ユーザがデバイス 0 を閉じる場合でも、JOB サーバで実行中のジョブが、主入出力デバイスに対して入力、または出力を実行できないことを意味します。
したがって、JOB サーバに入力を実行させたい場合は、以下を指定します。
このガイドラインに従わないと、JOB サーバで実行中のジョブは、主入出力デバイスに対する入力や出力を行う必要がある場合に停止することがあります。JOB の出力が頻繁に端末に表示される場合もありますが (SHARE 特権を持っている場合など)、通常は表示されません。
実行されないジョブに関するトラブルシューティング
ジョブが開始しない場合は、入出力指定をチェックしてください。InterSystems IRIS が要求デバイスを開くことができない場合、ジョブは開始されません。なお、NULL デバイス (UNIX® では /dev/null) はいつでも利用できます。
ジョブが開始されてもすぐに停止される場合は、適切なスワップ領域があることを確認してください。十分なスワップ領域がない場合、ジョブはエラーを受け取ります。JOB コマンドによって作成された新しいプロセスが、すぐに停止した場合や、プロセスの起動が完了する前に ^RESJOB ユーティリティで終了した場合、JOB コマンドは <HALTED> または <RESJOB> エラーを生成します。詳細は "HALT" コマンドを参照してください。
ジョブが開始されない場合は、JOB コマンドで正しいネームスペースを使用していることを確認してください。Exists()Opens in a new tab メソッドを使用して、ネームスペースが定義されているかどうかをテストすることができます。
WRITE ##class(%SYS.Namespace).Exists("USER"),! ; an existing namespace
WRITE ##class(%SYS.Namespace).Exists("LOSER") ; a nonexistent namespace
JOB コマンドが目的どおりに実行されない場合は、以下を試してください。
-
ルーチンを DO コマンドで実行します。
-
InterSystems IRIS でライセンス付与されているプロセスの数を超えていないことを確認してください。"インターシステムズ・クラス・リファレンス" の説明に従って、%SYSTEM.LicenseOpens in a new tab クラスのクラス・メソッドを使用して、使用できる InterSystems IRIS ライセンスの数を決定できます。
-
JOB コマンドに timeout パラメータがある場合は、システムの速度により指定されたタイムアウト時間に達していないかどうかを確認してください。
多数のジョブを同時に実行している場合、ルーチン・バッファもしくはライセンス・スロットを待っている間に、JOB コマンドが停止することがあります。Ctrl-C を使用して、JOB コマンドに割り込むことができます。
JOB コマンドの終了
ジョブ起動プロセスは、終了する前にそれを作成したプロセスがログオフされた場合でも、最後まで続行されます。
TCP デバイスを使用した JOB コマンド
JOB コマンドを使用して、TCP 並行サーバ を実装することができます。TCP 並行サーバを使用すると、複数のクライアントを同時に処理できます。このモードでは、クライアントは、サーバが他のクライアントのサービスを終了するまで待機する必要はありません。代わりに、クライアントがサーバに要求を送信するたびに、開いているクライアントに対して必要に応じて個別のサブジョブを生成します。このサブジョブが生成された直後に (JOB コマンドから制御が戻ります)、他のクライアントが処理を要求することがあります。サーバは、そのクライアントのサブジョブも同様に生成します。
非並行モードおよび並行モードのクライアント/サーバ接続
並行サーバは、ビット 4 またはビット 16 のビット・マスクが設定された switch プロセス・パラメータを指定して JOB コマンドを使用し、生成されたプロセスに入力および出力のプロセス・パラメータを渡します。
-
switch にビット 4 を指定する場合、常に、プロセス・パラメータ principal-input および principal-output の両方の TCP デバイスを指定する必要があります。以下のように、principal-input と principal-output の両方に同デバイスを使用する必要があります。
JOB child:(:4:tcp:tcp)
その後、生成されたプロセスは、この単一の入出力デバイスを以下のように設定します。
SET tcp=$IO
-
switch にビット 16 を指定する場合、以下のように、プロセス・パラメータ principal-input および principal-output の TCP デバイスに異なるデバイスを指定できます。
USE tcp
JOB child:(:16:input:output)
JOB コマンドの前の USE tcp は、(主デバイスではなく) 現在のデバイスを TCP デバイスとして指定します。その後、生成されたプロセスはこれらのデバイスを以下のように設定できます。
SET tcp=##class(%SYSTEM.INetInfo).TCPName()
SET input=$PRINCIPAL
SET output=$IO
WRITE tcp," ",input," ",output
4 ビットまたは 16 ビットが設定されている場合、JOB コマンドが、ジョブ起動プロセスに TCP ソケットを渡すことが重要となります。追加の機能ごとに適切なビット・コードを追加すると、JOB コマンドの他の機能と組み合わせることができます。例えば、switch が値 1 のビットを含むときは、シンボル・テーブルが渡されます。並行モードをオンにし、シンボル・テーブルを渡すには、switch の値を 5 (4+1) または 17 (16+1) にします。
JOB コマンドを実行する前に、TCP デバイスは以下の状態になる必要があります。
-
接続されている
-
TCP ポートで待ち受け状態にある
-
接続を受け入れ済みである
JOB コマンドの後、生成されているプロセスのデバイスは継続して TCP ポートで待ち受け状態にありますが、アクティブな接続は既に存在していません。アプリケーションは、JOB コマンドの実行後 $ZA 特殊変数をチェックし、TCP デバイスで CONNECTED ビットがリセットされていることを確認する必要があります。
生成されたプロセスは、指定の TCP デバイスを principal-input デバイスおよび principal-output デバイスに使用し、指定のエントリ・ポイントで開始します。子プロセスの TCP デバイス名は、親プロセスの名前と同じです。TCP デバイスには、付属のソケットが 1 つあります。USE コマンドは、“M” モードで TCP デバイス構築するために使用されます。これは “PSTE” と同等です。“P” (pad) オプションは、レコード・ターミネータ文字で出力を埋め込む際に必要です。このモードを設定すると、WRITE ! では LF (改行)、WRITE # では FF (改ページ) が送信されます。さらに、書き込みバッファがフラッシュされます。
生成したプロセスの TCP デバイスは、接続状態です。これは、デバイスをクライアントから開いた後に受け取る状態と同じです。生成されたプロセスは、TCP デバイスを明示的な USE 文で使用します。また、TCP デバイスを明示的に使用することもできます。
以下の例は、非常に単純な並行サーバです。このサーバは、クライアントからの接続を検出するたびに子ジョブを生成します。JOB は、並行サーバ・ビット 16 およびシンボル・テーブル・ビット 1 で構成される switch 値 17 を使用します。
server ;
SET io="|TCP|1"
SET ^serverport=7001
OPEN io:(:^serverport:"MA"):200
IF $TEST=0 {
WRITE !,"Cannot open server port"
QUIT }
ELSE { WRITE !,"Server port opened" }
loop ;
USE io READ x ; Read for accept
USE 0 WRITE !,"Accepted connection"
USE io
JOB child:(:17::) ; Concurrent server bit is on
GOTO loop
child ;
SET io=##class(%SYSTEM.INetInfo).TCPName()
SET input=$PRINCIPAL
SET output=$IO
USE io:(::"M") ; Ensure that "M" mode is used
WRITE $JOB,! ; Send job id on TCP device to be read by client
QUIT
client ;
SET io="|TCP|2"
SET host="127.0.0.1"
OPEN io:(host:^serverport:"M"):200 ; Connect to server
IF $TEST=0 {
WRITE !,"Cannot open connection"
QUIT }
ELSE { WRITE !,"Client connection opened" }
USE io READ x#3:200 ; Reads from subjob
IF x="" {
USE 0
WRITE !,"No message from child"
CLOSE io
QUIT }
ELSE {
USE 0
WRITE !,"Child is on job ",x
CLOSE io
QUIT }
子ジョブは、継承した TCP 接続を使用して、ジョブ ID (この場合は 3 文字とします) をクライアントに渡します。その後、子プロセスは終了します。クライアントは、サーバとの接続を開き、その状態で子のジョブ ID を読み取ります。この例では、変数 "host" の IPv4 の値 "127.0.0.1" がローカル・ホスト・マシンへのループバック接続を示しています (対応する IPv6 ループバックの値は "0:0:0:0:0:0:0:1" または "::1" です)。"host" にそのサーバの IP アドレス、または名前が設定される場合は、そのサーバからクライアントを別のマシンにセットアップすることもできます。IPv4 および IPv6 の形式に関する詳細は、"サーバ側プログラミングの入門ガイド" の “サーバ構成オプション” の章にある “IPv6 アドレスの使用” のセクションを参照してください。
原則では、子プロセスとクライアントは広範囲の通信を実行できます。複数のクライアントが同時に対応するサーバの子と通信できます。
子プロセスのパーティション・サイズを指定する
バックグラウンド・ジョブのパーティション・サイズ ($ZSTORAGE size) は、以下のように決定されます。
-
ジョブ・サーバがアクティブな場合、すべてのジョブ・サーバ・プロセスについて、ジョブ・パーティション・サイズは常に 262144 (キロバイト単位) になります。
-
ジョブ・サーバが非アクティブの場合、ジョブ・パーティション・サイズは、非バックグラウンド・ジョブの既定のパーティション・サイズ (bbsiz) に既定で設定されます。これは、JOB を発行する親プロセスのパーティション・サイズに関わらず、JOB を実行した際に有効になるシステム全体の既定です。
ジョブ・サーバが有効化されているが、それらのすべてがアクティブであり、ユーザが新しいジョブを開始した場合、そのジョブ・プロセスはジョブ・サーバ・プロセスにならないため、その $ZSTORAGE 値は bbsiz に既定で設定されます。これはジョブ・サーバがアクティブの場合にも当てはまりますが、ジョブのロードがジョブ・サーバ以外のプロセスで実行されるためです。
-
ジョブ・サーバが非アクティブの場合、JOB 文でジョブ起動子プロセスのパーティション・サイズを指定できます。ジョブ起動プロセスのパーティション・サイズ (キロバイト単位) は、JOB コマンドの第 2 プロセス・パラメータで指定します。例えば、JOB ^myroutine:(:8192) のように指定します。 指定する値は、32 の倍数で、範囲は、128 ~ 16384 です。また、既定のパーティション・サイズを超える値は指定できません。これは、既定未満の値を指定する目的でのみ使用できます。
オプションで、通常 JOB の第 2 プロセス・パラメータに入れる他のプロセス情報と組み合わせて、パーティション・サイズのプロセス・パラメータの値を指定することもできます。JOB コマンド JOB ^myroutine:(:544+1) について考えてみましょう。このコマンドは、ジョブを実行しているプロセスのシンボル・テーブルをジョブ起動プロセスに渡すこと、また、ジョブ起動プロセスのパーティション・サイズを 544 K にすることを指定しています。この第 2 パラメータで、2 つの値 (544 と 1) を 545 として渡すように指定することもできますが、544+1 とした方が分かりやすく、まったく同じ効果が得られます。
ジョブ自体が SET $ZSTORAGE を使用してプログラマチックに独自のパーティション・サイズを設定できることに注意してください。
関連項目