アドミッション API を呼び出す
ジョブを Slurm、LSF、Kubernetes 以外のもの(別のスケジューラー、ポータル、CI システム、ランチャースクリプトなど)で起動する場合は、LicOps のアドミッション API を直接呼び出します。JSON の本文を付けて HTTP POST を送信できるツールであれば、どれでも使えます。LicOps 側にインストールするものはありません。
インテグレーションキットから始める
OpenLM のインテグレーションキットには、リクエストの順序とあらゆる失敗時の経路をすでに処理している、すぐに使えるクライアントが 2 つ含まれています。
任意のコマンドをラップする
任意のコマンドをラップするには、bash/openlm-wrap.sh を使います。このスクリプトは、コマンドの実行中はシートを 1 つ確保し、コマンドがどのように終了してもそのシートを解放します。
export OL_ROUTER_URL=http://<licops-host>:8100
./bash/openlm-wrap.sh MLM MATLAB -- matlab -batch mysim
curl と jq が必要です。OL_COUNT でシート数を設定します。OL_FAIL_MODE は LicOps に到達できない場合の動作を決め、既定値は closed です。この場合、コマンドは実行されません。
Python から呼び出す
Python からは、python/openlm_licops.py を使います。必要なのは Python 3.7 の標準ライブラリだけです。
import os
from openlm_licops import LicOpsClient
ol = LicOpsClient("http://<licops-host>:8100")
with ol.seat(vendor="MLM", feature="MATLAB", count=1) as seat:
target = seat.dispatch(node_ip="10.42.7.31", job_id="918273")
os.environ["LM_LICENSE_FILE"] = target.license_file
run_the_application()
# The seat is released on the way out, including when the block raises.
ほかの言語でクライアントを作成する場合は、キットに含まれる 3 つのエンドポイントの OpenAPI 3.0 記述 openapi/openlm-licops-admission.yaml を使います。API ツールにインポートするか、そこからクライアントを生成してください。
3 つのリクエスト
3 つとも、http://<licops-host>:8100/api/v1/admission-controller 配下への、JSON の本文を付けた POST リクエストです。すべてのフィールドとレスポンスについては、API リファレンスを参照してください。
ジョブをキューに入れる前に admit する
まずセッション ID(UUID)を生成し、ジョブが終了するまで保持します。3 つのリクエストすべてに同じ ID を渡します。この ID によって、再試行が安全になります。同じ ID で admit を繰り返すと、セッションが有効な間は、2 つ目のシートがカウントされる代わりに、最初の応答が返されます。拒否された admit は保存されないため、繰り返すと改めて判定されます。ID を再利用するのは、ベンダー、フィーチャー、シート数が同じ場合だけにしてください。異なる場合は 400 で拒否されます。新しいジョブごとに新しい ID を使ってください。
curl -s -X POST http://<licops-host>:8100/api/v1/admission-controller/admit \
-H 'Content-Type: application/json' \
-d '{"sessionId":"8e29c1b2-6d3a-4f0e-9d51-7c2a4b6e8f10","vendor":"MLM","feature":"MATLAB","user":"jdoe","host":"login01","totalQuantity":1}'
{ "decision": "Admit", "sessionId": "8e29c1b2-6d3a-4f0e-9d51-7c2a4b6e8f10", "expiresAt": "2026-10-15T11:42:19Z", "reason": null }
200 は LicOps が判断を下したことを意味し、ジョブを許可したことを意味するわけではありません。decision を確認してください。
Admit: 先に dispatch しない限り、シートはexpiresAt(既定では 15 分後)まで、このセッションのものとしてカウントされます。Deny: 何もカウントされていません。理由はreasonに示されます。拒否理由を参照してください。ジョブは開始しないでください。後で改めて要求できます。
サーバーを指定することはありません。LicOps がアドミッションルールを適用して、サーバーを選びます。
ジョブの開始時に dispatch する
dispatch は、ジョブを実行するノード上で、できるだけ遅いタイミングで呼び出し、返されたサーバーを使います。
curl -s -X POST http://<licops-host>:8100/api/v1/admission-controller/dispatch \
-H 'Content-Type: application/json' \
-d '{"sessionId":"8e29c1b2-6d3a-4f0e-9d51-7c2a4b6e8f10","executionNodeIp":"10.42.7.31","jobId":"918273"}'
{
"sessionId": "8e29c1b2-6d3a-4f0e-9d51-7c2a4b6e8f10",
"hostName": "lic01.example.com",
"port": "27000",
"licenseFile": "27000@lic01.example.com",
"fallbackTargets": [
{ "hostName": "lic02.example.com", "port": "27000", "licenseFile": "27000@lic02.example.com" }
]
}
LM_LICENSE_FILE(または MLM_LICENSE_FILE などのアプリケーション独自の変数)に、licenseFile を返されたとおりに設定します。3 サーバー冗長構成のライセンスサーバーの場合、この値にはすでに 3 台すべてのマシンが含まれています。アプリケーションにフォールバック先のサーバーを与えるには、その後ろに fallbackTargets を、Linux では :、Windows では ; で連結します。
export LM_LICENSE_FILE=27000@lic01.example.com:27000@lic02.example.com
サーバーは、admit の時点で LicOps が予定したサーバーと異なる場合があります。その間にそのサーバーに障害が発生した場合、dispatch はシートを正常なサーバーに移します。常に dispatch が返したサーバーを使ってください。dispatch は、セッションを実行中のタイムアウト(既定では 2 時間)まで延長します。
ジョブの終了時に release する
シートを解放するには、次のコマンドを実行します。
curl -s -X POST http://<licops-host>:8100/api/v1/admission-controller/release \
-H 'Content-Type: application/json' \
-d '{"sessionId":"8e29c1b2-6d3a-4f0e-9d51-7c2a4b6e8f10"}'
release は常に 200 を返すため、2 回実行される可能性のある trap や finally ブロックから呼び出しても、一度も許可されなかったジョブに対して呼び出しても安全です。ジョブがどの経路で終了しても release が抜け落ちないように、admit の前に設定しておきます。release の時点で LicOps に到達できない場合は、ログに記録して処理を続けます。release の失敗を理由にジョブを失敗させてはいけません。シートは、セッションがタイムアウトした時点で LicOps が回収します。
エラーではない応答に対処する
エラーではない応答、その意味、対処を次の表に示します。
| 応答 | 意味 | 対処 |
|---|---|---|
admit の 503(Retry-After 付き) | LicOps が起動した直後で、OpenLM Platform に追いついていません。 | Retry-After の秒数(既定値は 10)だけ待ってから、同じセッション ID で再度 admit します。ジョブを失敗させないでください。 |
admit の 400 | 本文が無効です。sessionId、vendor、feature のいずれかが空であるか、シート数が 1 未満であるか、セッション ID が異なるベンダー、フィーチャー、シート数で再利用されています。 | リクエストを修正します。よくある原因は空のシェル変数です。 |
dispatch の 404 | 該当するセッションがありません。ID が間違っているか、セッションがすでに終了しているか、ジョブの開始前に admit タイムアウトが切れています。 | 新しいセッション ID で再度 admit します。dispatch は再試行しないでください。 |
dispatch の 503、ThrottleDeferred | Throttle ルールがチェックアウトのペースを調整しています。 | Retry-After の時間だけ待ってから、同じセッション ID で再度 dispatch します。シートは確保されたままなので、再度 admit しないでください。 |
dispatch の 503、NoCapacityAtDispatch | シートのあるサーバーに障害が発生し、プール内のほかのサーバーにも空きシートがありません。 | LicOps はセッションを解放済みで、Retry-After も送信しません。新しいセッション ID でもう一度 admit します。 |
独自クライアントのチェックリスト
クライアントが次のことを行っていることを確認します。
- セッション ID は自分で生成し、ジョブが終了するまで保持します。
- admit の
200は「判断が届いた」という意味として扱い、そのうえでdecisionを確認します。 - admit の
503は、拒否ではなく一時的な待機として扱います。 NoServerAvailableとNoCapacityは区別してログに記録します。前者は通常、ベンダーまたはフィーチャーのつづりの誤りを、後者は実際のシート不足を意味します。- dispatch はジョブの配置後に行い、返されたサーバーを使います。
- dispatch が
503ThrottleDeferredを返したら、同じ ID で再度 dispatch します。503NoCapacityAtDispatchを返したら、新しい ID で admit します。 - release は、どのような終わり方でも実行されるコードから行い、admit の前に設定しておきます。
- release の失敗を理由にジョブを失敗させないでください。
- LicOps の応答が遅くてもジョブの投入が止まらないように、2~10 秒の短い HTTP タイムアウトを使います。
- LicOps に到達できない場合の admit と dispatch の動作を個別に決め、その決定を記録しておきます。
ドキュメントチームは、大規模言語モデルを使ってこのページを下書きすることがあります。公開前に、テクニカルライターがすべてのページをレビューし、製品と照らし合わせて検証します。最終的な判断は人間が行います。