> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-JobQueue

非同期ジョブキュー




GS2-JobQueue はゲームサーバー上で実行する処理を非同期に積み上げるためのジョブキュー機能を提供します。

ゲームの処理には、すぐに結果を返す必要のないものや、サーバー側で時間をかけて段階的に進めたいものがあります。
そのような処理を「ジョブ」として登録し、ネームスペースの設定に応じて、サーバーの自動実行または明示的な `Run` API 呼び出しによって実行できます。

## 主な用途

- GS2-Script を非同期に実行するための実行基盤
- 長時間処理を細かいステップに分割し、ステップごとにジョブとして登録して順次処理する
- ログイン中に発生したリワード配布などをまとめてサーバー側でトランザクション発行・実行
- 他マイクロサービスの完了通知ハンドラとして、後続処理を非同期に行う

```mermaid
graph LR
  Producer["ジョブ登録元<br/>(他のマイクロサービス / GS2-Script)"] --> Queue["GS2-JobQueue"]
  Queue --> Run["プレイヤーが Run を実行<br/>または 自動実行"]
  Run --> Script["GS2-Script"]
  Script -- 成功 --> Result["JobResult として記録"]
  Script -- 失敗 --> Retry{"最大試行回数<br/>に到達?"}
  Retry -- No --> Queue
  Retry -- Yes --> DeadLetter["DeadLetterJob として保管"]
```

## 自動実行モード

ネームスペースの設定で `enableAutoRun` を有効にすると、ジョブ登録時にサーバーでの実行が開始されます。プレイヤーによる次の API 呼び出しを待つ仕組みではありません。
既定値は `false` です。サーバーの自動実行を選ぶ場合は明示的に設定してください。

`enableAutoRun` を無効にする場合は、クライアントから明示的に `Run` API を呼び出してジョブを実行する必要があります。

## ジョブ結果

ジョブの実行結果は試行回数(`tryNumber`)ごとに `JobResult` として記録されます。
`JobResult` には `statusCode`（スクリプト実行の HTTP ステータス）と `result`（応答本文）が含まれます。独立したスクリプト実行ログは含まれません。

## 通知設定

ネームスペースの設定で `runNotification` ・ `pushNotification` を構成しておくと、ジョブが実行されたとき、または新規にジョブがキューに積まれたときに GS2-Gateway を経由してクライアントへ通知できます。
この通知をフックに、クライアント側で残り情報を再取得するといった連携が可能です。

## トランザクションアクション

GS2-JobQueue は他のマイクロサービスから完了通知の受け先として呼び出されることが多く、トランザクションアクションとしてジョブ登録を提供しています。

- 入手アクション: ジョブをユーザーのキューに登録

たとえば GS2-Mission の完了報酬として GS2-JobQueue にジョブを積み、後でまとめて GS2-Script を実行するといった構成が可能です。

## マスターデータ管理

GS2-JobQueue はマスターデータを持ちません。
振る舞いはネームスペースの設定でのみ制御します。

## 実装例

### 自分のキューに積まれているジョブを実行

`enableAutoRun` を無効にした場合や、明示的にジョブの消化を進めたい場合に呼び出します。
`Run` を呼び出すと、ジョブを1件取り出して GS2-Script を実行し、その結果を返します。
`IsLastJob` が `true` であれば、これ以上消化すべきジョブが残っていないことを示します。



**Unity**
```csharp

    var domain = gs2.JobQueue.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var result = await domain.RunAsync(
    );
    var isLastJob = domain.IsLastJob;
    var needRetry = result.NeedRetry;
```
**Unreal Engine 5**
```cpp

    const auto Domain = Gs2->JobQueue->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto Future = Domain->Run(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;
    const auto IsLastJob = Domain->IsLastJob();
    const auto NeedRetry = Future->GetTask().Result()->NeedRetry();
```
**Godot**
```gdscript

var domain = ez.job_queue.namespace_("namespace-0001").me(game_session)
var async_result = await domain.run()
if async_result.error != null:
    push_error(str(async_result.error))
    return
var is_last_job = domain.is_last_job
var need_retry = async_result.result.need_retry

```


### ジョブの実行結果を取得

特定のジョブの特定の試行回数の実行結果を取得します。



**Unity**
```csharp

    var item = await gs2.JobQueue.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Job(
        jobName: "job-0001"
    ).JobResult(
        tryNumber: 1
    ).ModelAsync();
```
**Unreal Engine 5**
```cpp

    const auto Domain = Gs2->JobQueue->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Job(
        "job-0001" // jobName
    )->JobResult(
        1 // tryNumber
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;
    const auto Result = Future->GetTask().Result();
```
**Godot**
```gdscript

var domain = ez.job_queue.namespace_(
        "namespace-0001"
    ).me(game_session).job(
        "job-0001"
    ).job_result(
        1 # try_number
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


### ジョブの状態を取得

キューに積まれているジョブの最新状態を取得します。
ジョブの現在の試行回数や登録された GS2-Script の情報などを確認できます。



**Unity**
```csharp

    var item = await gs2.JobQueue.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Job(
        jobName: "job-0001"
    ).ModelAsync();
```
**Unreal Engine 5**
```cpp

    const auto Future = Gs2->JobQueue->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Job(
        "job-0001" // jobName
    )->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;
    const auto Result = Future->GetTask().Result();
```
**Godot**
```gdscript

var domain = ez.job_queue.namespace_(
    "namespace-0001"
).me(game_session).job("job-0001")
var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return
var item = async_result.result

```


## 詳細なリファレンス

[GS2-JobQueue API リファレンス](../../api_reference/job_queue)



