JOB (ObjectScript)
構文
JOB:pc jobargument,...
J:pc jobargument,...
jobargument は以下のいずれかになります。
ローカル・ジョブ
routine(routine-params):(process-params):timeout
routine(routine-params)[joblocation]:(process-params):timeout
routine(routine-params)|joblocation|:(process-params):timeout
##class(className).methodName(args):(process-params):timeout
..methodName(args):(process-params):timeout
$CLASSMETHOD(className,methodName,args):(process-params):timeout
リモート・ジョブ
routine[joblocation]
routine|joblocation|
引数
引数 | 説明 |
---|---|
pc | オプション — 後置条件式 |
routine | JOB で作成されたプロセスによって実行されるルーチン |
routine-params | オプション — ルーチンに渡されるパラメータの、コンマ区切りのリストこのパラメータは、値、式、もしくは既存のローカル変数名です。指定された場合は、最後の括弧が必須です。ルーチン・パラメータは、ローカル・ジョブにのみ渡されます。 |
className.methodName(args) ..methodName(args) |
JOB で作成されたプロセスによって実行されるクラス・メソッドclassName を $SYSTEM にすることはできませんが、%SYSTEM にすることは可能です。className の代わりに .. を指定すると、JOB は、現在のクラス・コンテキスト ($THIS クラス) を使用します。variable 引数のコンマ区切りのリストはオプションですが、括弧で囲む必要があります。引数は省略できません。$CLASSMETHOD の使用の詳細は、"オブジェクトへの動的アクセス" を参照してください。 |
process-params | オプション — コロンで区切られた位置パラメータのリスト。ジョブの環境内のさまざまな要素を設定するために使用されます。process-params リストは括弧で囲まれ、括弧で囲んだリストの前にコロンが付きます。すべての process-params はオプションです。括弧は必須です。位置パラメータを指定しないことを示すには、コロンを記述する必要がありますが、末尾のコロンは省略できます。process-params 引数は、ローカル・ジョブに対してのみ指定できます。 |
timeout | オプション — ジョブ起動プロセスの開始を待つ秒数。秒の小数部は整数部分に切り捨てられます。最初のコロンは必須です。timeout 引数は、ローカル・ジョブに対してのみ指定できます。省略した場合、InterSystems IRIS は無限に待機します。 |
joblocation |
オプション — ローカル・ジョブまたはリモート・ジョブを実行するシステムおよびディレクトリを指定するために使用される、明示的または暗黙的なネームスペース。暗黙のネームスペースは、"^^dir" のように 2 つのキャレット文字が先行するディレクトリ・パスです。joblocation は、角括弧 ([ ])、または垂直バー ( | ) で囲まれます。 クラス・メソッドをジョブ起動する場合、joblocation を指定することはできません。joblocation でリモート・システムを指定する場合、routine-params、process-params、または timeout を指定することはできません。 joblocation でローカル・ジョブを指定する場合、最初のプロセス・パラメータ (nspace) を指定することはできません。joblocation パラメータと競合するからです。したがって、2 番目、3 番目、および 4 番目のプロセス・パラメータのみが指定され、指定されない nspace パラメータはコロンで示される必要があります。 |
概要
JOB は、ジョブ、ジョブ起動プロセス、もしくはバックグラウンド・ジョブと呼ばれる個別のプロセスを作成します。作成されたプロセスは、現在のプロセスと関係なく、バックグラウンドで実行されます。通常は、ユーザ対話も行いません。ジョブ起動プロセスは、JOB コマンドで明示的に指定されたものを除いて、呼び出されたプロセスからの構成環境を継承します。例えば、ジョブ起動プロセスは、システムの既定のロケールではなく、親プロセスのロケール設定を継承します。
これに対し、DO コマンドで呼び出されたルーチンは、現在のプロセスの一部としてフォアグラウンドで実行されます。
JOB は使用中のローカル・システムに、ローカル・プロセスを作成するか、他のシステムでリモート・プロセスの作成を実行することもできます。リモート・ジョブに関する詳細は、"リモート・ジョブ" を参照してください。
ジョブが開始されると、InterSystems IRIS は、ユーザが記述した JOB^%ZSTART ルーチンを呼び出すことができます。ジョブが終了すると、InterSystems IRIS は、ユーザが記述した JOB^%ZSTOP ルーチンを呼び出すことができます。これらのエントリ・ポイントは、ジョブ・アクティビティのログの管理および生じた問題のトラブルシューティングに使用できます。詳細は、"InterSystems IRIS ^%ZSTART および ^%ZSTOP ルーチンの使用法" を参照してください。
引数
pc
オプションの後置条件式です。InterSystems IRIS は、後置条件式が True (0 以外の数値に評価される) の場合に JOB を実行します。InterSystems IRIS は、後置条件式が False (0 に評価される) の場合はコマンドを実行しません。詳細は、"コマンド後置条件式" を参照してください。
routine
開始されるプロセスです。以下の形式のいずれかで指定することができます。
プロセス指定 | 説明 |
---|---|
label | 現在のルーチン内の行ラベルを指定します。 |
^routine | ディスクに保存されているルーチンを指定します。InterSystems IRIS は、ディスクからそのルーチンをロードし、そのルーチン内の最初の実行可能コード行から実行を開始します。 |
label^routine | ディスクに保存されている指定したルーチン内の行ラベルを指定します。InterSystems IRIS は、ディスクからそのルーチンをロードし、指定されたラベルから実行を開始します。 |
label+offset label+offset^routine |
行ラベルからの指定された行数のオフセットを指定します。オフセットを使用すると、プログラムのメンテナンスに関する問題が生じることがあるので、お勧めしません。IRISSYS % ルーチンの呼び出し時における offset の指定はできません。指定しようとすると、InterSystems IRIS は <NOLINE> エラーを発行します。 |
プロシージャ・ブロック内では、JOB コマンドを呼び出すと、プロシージャ・ブロックの範囲外にある子プロセスが開始します。そのため、プロシージャ・ブロック内の label 参照を解決できません。この結果、プロシージャ内のラベルを参照する JOB では、プロシージャはプロシージャ・ブロックを使用できません。
存在しないラベルを指定した場合、InterSystems IRIS は <NOLINE> エラーを返します。存在しないルーチンを指定した場合、InterSystems IRIS は <NOROUTINE> エラーを返します。これらのエラーの詳細は、"$ZERROR" 特殊変数を参照してください。
routine-params
コンマで区切られた値のリスト、式、または既存のローカル変数名です。括弧は必須です。このリストは、実パラメータ・リストと呼ばれます。ルーチンには、仮パラメータ・リストが必須です。また、このリスト内のパラメータ数は、実パラメータ・リスト内のパラメータ数以上でなければなりません。指定した実パラメータの方が多い場合、InterSystems IRIS は <PARAMETER> エラーを返します。呼び出されるルーチンに仮パラメータ・リストが含まれている場合は、それを囲む括弧を指定する必要があります。パラメータを渡さない場合も同様です。routine-params のリストから項目を省略することはできません。
ルーチン・パラメータは値によってのみ渡すことができますつまり、配列を渡すことはできないということです。この点で、値でも参照でもパラメータを渡すことができる DO コマンドとは異なります。この制限により、JOB コマンドでは配列を渡すことができません。配列は、参照でしか渡すことができないからです。
ジョブ起動プロセスにオブジェクト参照 (oref) を渡すことはできません。呼び出し元のプロセス・コンテキスト内に存在するオブジェクトへの参照は、新しいジョブ起動プロセス・コンテキスト内では参照できないためです。oref を渡そうとすると、ジョブ起動プロセスに空文字列 ("") が渡されます。
ルーチンを開始すると、InterSystems IRIS はすべての式を評価し、実リストの各パラメータの値をその位置に従って、仮リストの対応変数にマップします。仮リスト内の変数が、実リスト内のパラメータよりも多い場合は、余った変数は未定義のままになります。
ルーチン・パラメータは、ローカル・プロセスにのみ渡されます。リモート・ジョブを作成しているときは、ルーチン・パラメータを指定することはできません。"リモート・ジョブ" を参照してください。
process-params
コロンで区切られた位置パラメータのリスト。ジョブの環境内のさまざまな要素を設定するために使用されます。先頭のコロンと括弧は必須です。すべての位置パラメータはオプションです。process-params には、最大 6 つの位置パラメータを指定できます。これらの 6 つのパラメータは以下のとおりです。
(nspace:switch:principal-input:principal-output:priority:os-directory)
これらのパラメータの位置は決められているので、必ず示した順に指定してください。指定するパラメータの前に省略するパラメータがある場合は、プレースホルダとしてコロンを付ける必要があります。
プロセス・パラメータは、リモート・ジョブに対しては指定できません。
以下のテーブルは、プロセス・パラメータの説明です。
プロセス・パラメータ | 概要 |
---|---|
nspace | プロセスの既定のネームスペースです。指定された routine は、このネームスペースから引き出されます。nspace を省略した場合、現在の既定のネームスペースが、そのジョブ起動プロセスの既定のネームスペースになります。無効なネームスペースを指定した場合は、ジョブが開始されない可能性があります。ローカル・ジョブでは、プロセス・パラメータとして joblocation 引数とネームスペースの両方を指定することはできません。nspace プロセス・パラメータを省略し、プレースホルダのコロンを保持する必要があります。 |
switch |
以下のうち 1 つ以上の合計で構成されている整数 0 または複数の以下のフラグを表すことができる整数ビット・マスク 1 — 生成されたジョブにシンボル・テーブルを渡します。 2 — JOB サーバは使用しません。 4 — 主入出力デバイス ($PRINCIPAL) を使用して、開いている TCP/IP ソケットを、生成されたジョブに渡します。(非推奨。代わりに 16 を使用してください。以下を参照してください。) 8 — 生成されたジョブの 2 桁の年に対するプロセス独自のウィンドウが、システム全体の既定のスライディング・ウィンドウ定義になるように設定します。特に設定されない場合、生成されたジョブは、JOB コマンドを実行したプロセスのスライディング・ウィンドウ定義を継承します。 16 — 現在の主入出力デバイス ($IO) を使用して、開いている TCP/IP ソケットを、生成されたジョブに渡します。 128 ~ 16384 (32 の倍数) — ジョブ起動子プロセスのパーティション・サイズ (KB) を指定する追加の整数値です。詳細は、"子プロセスのパーティション・サイズを指定する" を参照してください。 switch 値は、これらの整数の組み合わせの合計を設定できます。例えば、switch 値 13 (1 + 4 + 8) はシンボル・テーブル (1) を渡し、開いている TCP/IP ソケット (4) を渡し、システム全体の既定である 2 桁の年 (8) のための、プロセス独自のウィンドウを設定します。 スイッチのブロックは、%SYSTEM.UtilOpens in a new tab クラスの CheckSwitch()Opens in a new tab メソッドを使用して決定できます。 |
principal-input | プロセスの主入出力デバイスです。既定値は NULL デバイスです。 |
principal-output |
プロセスの主出力デバイスです。既定値は、principal-input に指定するデバイスか、どちらのデバイスも指定していない場合は NULL デバイスです。 UNIX® : どちらのデバイスも指定していない場合、プロセスは、JOB コマンドで開始されたプロセスの既定の主デバイス /dev/null を使用します。 |
priority | UNIX® — 子プロセスの優先度を指定する整数 (オペレーティング・システムの制約に従います)。指定しない場合は、子プロセスは親プロセスのベース優先度とシステム定義のジョブ優先度の変更子を使用します。$VIEW 関数を使用して、ジョブの現在の優先度を決定することができます。Windows の標準優先度は 7 です。UNIX® の優先度は、-20 ~ 20 の範囲で、標準優先度は 0 です。UNIX® では、root として実行していない限り、プロセス自身でその優先度を上げることはできません。 |
os-directory | ファイル入出力用のオペレーティング・システムの作業ディレクトリ。既定では、親プロセスから継承した作業ディレクトリを使用します。このパラメータは、システムによっては無視される可能性があります。 |
Switch 4 および Switch 16
渡された TCP デバイスが子ジョブの主デバイスとして確立されるため、switch=4 の使用はお勧めしません。この場合、子ジョブは TCP リモート接続が切断されたことを検出したときに停止する場合があり、エラー・トラップを実行しません。代わりに、ユーザは、switch=16 を使用してから、子ジョブで %SYSTEM.INetInfo.TCPName()Opens in a new tab メソッドを使用し、渡された TCP デバイスの名前を取得する必要があります。この場合、子ジョブの主デバイスが渡された TCP デバイスではないため、子ジョブは TCP リモート接続が切断されたことを検出ときに実行を継続する場合があります。
timeout
ジョブがタイムアウトし、中止される前に、ジョブ起動プロセスの開始を待機する秒数です。最初のコロンは必須です。timeout は、整数値または式として指定する必要があります。ジョブ起動プロセスがタイムアウトになると、InterSystems IRIS はプロセスを中止し、$TEST 特殊変数を 0 (FALSE) に設定します。実行は、呼び出しルーチンの次のコマンドから続行します。エラー・メッセージは発行されません。ジョブ起動プロセスが成功すると、InterSystems IRIS は $TEST を 1 (TRUE) に設定します。$TEST は、ユーザが設定することもできます。また、LOCK、OPEN、または READ のタイムアウトで設定されることもあります。
タイムアウトは、ローカル・プロセスに対してのみ指定できます。
例
以下の例は、監視ルーチンをバックグラウンドで開始します。プロセスが 20 秒以内に開始されない場合、InterSystems IRIS は $TEST を False (0) に設定します。
JOB ^monitor::20
WRITE $TEST
以下の例は、Disp という名前の行ラベルで、監視ルーチンの実行を開始します。
JOB Disp^monitor
以下の例は、ADD ルーチンを開始します。このとき、変数 num1 内の値、値 8、および式 a + 2 の結果の値がルーチンに渡されます。ADD ルーチンには、少なくとも 3 つのパラメータを含む、仮パラメータ・リストが含まれます。
JOB ^Add(num1,8,a+2)
以下の例は、ADD ルーチンを開始します。このルーチンは仮パラメータ・リストを持っていますが、パラメータは渡されません。この場合、ADD ルーチンは、呼び出し元のルーチンから値を受け取らないので、その仮パラメータに既定値を代入するコードが含まれていなければなりません。
JOB ^Add()
以下の例は、ラベル AA の現在のルーチンで実行するプロセスを作成します。プロセス・パラメータは、現在のシンボル・テーブルをルーチンに渡します。JOB サーバを使用できます。
JOB AA:("":1)
以下の例では、ルーチン・パラメータ VAL1 および文字列 "DR." を、現在のネームスペースの、エントリ・ポイント ABC で開始される ^PROG ルーチンに渡します。このルーチンは 2 つの引数を要求します。InterSystems IRIS は現在のシンボル・テーブルをこのジョブに渡しません。また、使用できる場合は JOB サーバを使用し、主入出力デバイスとして tta5: を使用します。
JOB ABC^PROG(VAL1,"DR."):(:0:"tta5:")
以下は、10 秒でタイムアウトするクラス・メソッドのジョブ起動の例です。主入出力デバイスとして tta5: を使用します。
以下の例では、##class 構文を使用してクラス・メソッドを呼び出します。
JOB ##class(MyClass).Run():(:0:"tta5:"):10
以下の例では、$CLASSMETHOD 関数を使用してクラス・メソッドを呼び出します。
JOB $CLASSMETHOD("MyClass","Run"):(:0:"tta5:"):10
以下の例では、相対ドット構文 (..) を使用して現在のオブジェクトのメソッドを参照します。
JOB ..CleanUp():(:0:"tta5:"):10
または単純に以下のようになります。
JOB ..CleanUp()::10
詳細は、"オブジェクト特有の ObjectScript の機能" を参照してください。
メモ
InterSystems IRIS が割り当てるジョブ番号とメモリ・パーティション
ジョブ起動プロセスの開始後、InterSystems IRIS は、そのプロセスに個別のメモリ・パーティションと、一意のジョブ番号 (またはプロセス ID、PID とも呼ばれます) を割り当てます。ジョブ番号は、特殊変数 $JOB に保存されます。ジョブの状態 (そのジョブが JOB コマンドで開始されたか否かも含む) は、$ZJOB 特殊変数に格納されます。
ジョブ起動プロセスは、それぞれ別個のメモリ・パーティションを保持しているので、そのプロセスを作成したプロセスやジョブ起動プロセスが共通のローカル変数環境を共有することはありません。ジョブ起動プロセスを開始するときには、パラメータ渡し (routine–params) により、現在のプロセスからジョブ起動プロセスに値を渡すことができます。
JOB コマンドが失敗する一般的な原因は以下のとおりです。
-
空きパーティションがない
-
process—params で指定された特性でパーティションを作成する十分なメモリがない
プラットフォームで異なるジョブ起動プロセスの許可
JOB コマンドにより作成されたプロセスは、インターシステムズのサービス・アカウント・ユーザとして実行します。つまり、インターシステムズのサービス・アカウントに、必要なすべてのリソースへの明示的なアクセス権が付与されていることを確認する必要があります。
生成されたジョブ・プロセスは JOB コマンドを発行したプロセスのユーザ ID 以外で実行することもできます。生成されたジョブ・プロセスのユーザ ID はプラットフォームによって、以下のように異なります。
-
Windows プラットフォームでは、ジョブ・プロセスは InterSystems IRIS インスタンス用に確立されたユーザ ID を使用します。
-
UNIX® プラットフォームでは、ジョブ・プロセスは JOB コマンドを発行したプロセスのユーザ ID を使用します。
したがって、ジョブを生成するときは、ジョブ・プロセスのユーザ ID に、ジョブ実行中に読み書きされるファイルを使用するために必要な許可があることを確認する必要があります。
ジョブ間の通信
値渡しのパラメータは、1 方向のみ、およびジョブの起動時のみ発生します。プロセス相互の通信を行うには、双方が合意したグローバル変数を使用する必要があります。このような変数は、プロセス間の情報交換を可能にすることだけが目的なので、一般にスクラッチ・グローバルと呼ばれます。
-
プロセスでは、%SYSTEM.EventOpens in a new tab クラス・メソッドを使用して、ジョブ間の通信を行えます。
-
特殊なプロセス・パラメータを指定することによって、現在のプロセスのすべてのローカル変数を、呼び出されたプロセスに渡すことができます。
-
プロセスでは、IPC (プロセス間通信) デバイス (デバイス番号 224 ~ 255) を介してジョブ間の通信を行うこともできます。また、UNIX® オペレーティング・システムの場合は、UNIX® のパイプを介した通信が可能です。
デバイス所有権の設定
InterSystems IRIS は、新しいプロセスのデバイス所有権を扱うコード (OPEN コマンドや USE コマンド) を呼び出し先ルーチンが含むと想定しています。既定のデバイスは、NULL デバイスです。
InterSystems IRIS は、サインイン時に開始されたプロセス以外のプロセスには、既定のデバイスを割り当てません。
ジョブ優先度の設定
%PRIO ユーティリティを使用すると、UNIX® のジョブ起動プロセスの実行優先度を制御できます。使用可能なオプションは、NORMAL (負荷分散を使用して CPU の使用効率を調整)、LOW および HIGH です。優先度が HIGH の場合、ジョブ起動プロセスは、対話型プロセスと対等に CPU リソースを取り合います。
InterSystems IRIS で、ジョブ起動プロセスに対して既定の優先度を設定することもできます。
BatchFlag()Opens in a new tab メソッドを使用すると、プロセスをバッチ・モードで実行するように設定できます。バッチ・モードのプロセスは、バッチでないプロセスよりも優先度が低くなります。
Raw パーティションで JOB コマンドを使用する (UNIX®)
以下のいずれかの方法で、JOB コマンドを Raw パーティションで使用できます。
-
Raw パーティションで JOB コマンドを実行する
-
他のネームスペースで JOB コマンドを実行し、JOB コマンドのプロセス・パラメータ nspace として、ロー・パーティションを指定するこの nspace は、暗黙のネームスペースです。暗黙のネームスペースは、"^^dir" のように 2 つのキャレット文字が先行するディレクトリ・パスです。暗黙のネームスペースの構文については、"拡張グローバル参照" を参照してください。
Raw パーティションで実行しているコマンドとジョブ起動プロセスの場合、ファイル名を参照するときは常に、フル・パス名を指定する必要があります。また、"." や ".." で開始するパス名は使用してはなりません。これらは特殊な UNIX® ファイルであり、Raw パーティションには存在しないからです。これらの規則のいずれかに違反すると、<DIRECTORY> エラーが発生します。
現在のネームスペースのフル・パス名を取得するには、以下の例に示すように、NormalizeDirectory()Opens in a new tab メソッドを呼び出します。
WRITE ##class(%Library.File).NormalizeDirectory("")
また、ObjectScript の JOB コマンドの代わりに、UNIX® のジョブ制御構文 (&) を使用することもできます。
リモート・ジョブ
リモート・ジョブを開始する前に、ECP接続を確立し、netjob パラメータを True に設定する必要があります。これにより、サーバはリモート ECP クライアント・システムからのジョブ要求を処理することができます。
リモート・ジョブ要求を受信する予定のシステムには、あらかじめその機能を設定しておく必要があります。
受信システムで管理ポータルに進み、[システム管理]、[構成]、[追加の設定]、[メモリ詳細] の順に選択します。表示して編集する netjob を見つけます。“true” の場合、ECP を介して着信するリモート・ジョブ要求は、このサーバで処理されます。既定は “true” です。
リモート・システムのライセンスでは、リモートで開始されるジョブを実行できる十分なユーザがサポートされている必要があります。"インターシステムズ・クラス・リファレンス" の説明に従って、%SYSTEM.LicenseOpens in a new tab クラスのクラス・メソッドを使用して、使用できる InterSystems IRIS ライセンスの数を決定できます。
リモート・ジョブ要求のジョブ構文
以下の構文を使用すると、ある InterSystems IRIS システムから別の InterSystems IRIS システムへ、リモート・ジョブを送信できます。
JOB routine[joblocation]
JOB routine|joblocation|
2 つの形式は類似しています。joblocation パラメータを囲むのは、角括弧 ([ ])、または垂直バー ( | ) のどちらでも使用できます。リモート・ジョブは、ルーチン・パラメータ、プロセス・パラメータ、またはタイムアウトを渡すことはできません。
-
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 サーバに入力を実行させたい場合は、以下を指定します。
-
代替入力デバイス
-
出力デバイス用の NULL デバイス (出力を表示させたくない場合)
このガイドラインに従わないと、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 を使用してプログラマチックに独自のパーティション・サイズを設定できることに注意してください。