GS2-JobQueue
GS2-JobQueue はゲームサーバー上で実行する処理を非同期に積み上げるためのジョブキュー機能を提供します。
ゲームの処理には、すぐに結果を返す必要のないものや、サーバー側で時間をかけて段階的に進めたいものがあります。 そのような処理を「ジョブ」としてキューに登録しておき、後からプレイヤーがアクセスしたタイミングや明示的なAPI呼び出しによって実行することができます。
主な用途
- GS2-Script を非同期に実行するための実行基盤
- 長時間処理を細かいステップに分割し、ステップごとにジョブとして登録して順次処理する
- ログイン中に発生したリワード配布などをまとめてサーバー側でトランザクション発行・実行
- 他マイクロサービスの完了通知ハンドラとして、後続処理を非同期に行う
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処理の最後にユーザーのキューに積まれているジョブを自動的に実行します。
プレイヤーがアプリを操作するだけで、サーバー側に積まれたジョブが順次消化されていきます。
enableAutoRun を無効にする場合は、クライアントから明示的に Run API を呼び出してジョブを実行する必要があります。
ジョブ結果
ジョブの実行結果は試行回数(tryNumber)ごとに JobResult として記録されます。
JobResult には GS2-Script の終了コード・実行ログ・結果ペイロードなどが含まれ、後から実行履歴を確認することができます。
通知設定
ネームスペースの設定で runNotification ・ pushNotification を構成しておくと、ジョブが実行されたとき、または新規にジョブがキューに積まれたときに GS2-Gateway を経由してクライアントへ通知できます。
この通知をフックに、クライアント側で残り情報を再取得するといった連携が可能です。
トランザクションアクション
GS2-JobQueue は他のマイクロサービスから完了通知の受け先として呼び出されることが多く、トランザクションアクションとしてジョブ登録を提供しています。
- 入手アクション: ジョブをユーザーのキューに登録
たとえば GS2-Mission の完了報酬として GS2-JobQueue にジョブを積み、後でまとめて GS2-Script を実行するといった構成が可能です。
マスターデータ管理
GS2-JobQueue はマスターデータを持ちません。 振る舞いはネームスペースの設定でのみ制御します。
実装例
自分のキューに積まれているジョブを実行
enableAutoRun を無効にした場合や、明示的にジョブの消化を進めたい場合に呼び出します。
Run を呼び出すと、ジョブを1件取り出して GS2-Script を実行し、その結果を返します。
IsLastJob が true であれば、これ以上消化すべきジョブが残っていないことを示します。
var domain = gs2.JobQueue.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var result = await domain.RunAsync(
);
var isLastJob = domain.IsLastJob;
var needRetry = result.NeedRetry; 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;ジョブの実行結果を取得
特定のジョブの特定の試行回数の実行結果を取得します。
var item = await gs2.JobQueue.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Job(
jobName: "job-0001"
).JobResult(
tryNumber: 1
).ModelAsync(); 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();ジョブの状態を取得
キューに積まれているジョブの最新状態を取得します。 ジョブの現在の試行回数や登録された GS2-Script の情報などを確認できます。
var item = await gs2.JobQueue.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Job(
jobName: "job-0001"
).ModelAsync(); 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();