NAV
Unity (UniTask) Unity Unity (Legacy) Unreal Engine 5 Unreal Engine 4

GS2-JobQueue

GS2-SDK for Game Engine Reference

SDK for Game Engine

Models

EzJob

Job

A job queue is a mechanism for delaying the execution of a process rather than completing it immediately.
For example, when a character is acquired, the process that must be executed immediately is to store the character in the possession.
On the other hand, a process that does not have to be executed immediately is the process of `registering the character in the picture book.

By processing these processes that do not need to be processed immediately via a job queue, the design can be made more resilient to failures.
This is because even if the illustrated book service is stopped due to some failure, the game can continue without being registered in the illustrated book.
Even if the process packed in the job queue fails, it can be retried after the failure is resolved, resulting in a correct state.

GS2 recommends this kind of result matching process, and in various situations, job queues are used for delayed processing.

Type Description
jobId string Job GRN
scriptId string Script GRN
args string argument
currentRetryCount int Current retry count
maxTryCount int Maximum number of attempts

EzJobResult

Type Description
statusCode int status code
result string Response Content

EzJobEntry

Type Description
scriptId string Script GRN
args string argument
maxTryCount int Maximum number of attempts

EzJobResultBody

Type Description
tryNumber int Number of attempts
statusCode int status code
result string Response Content
tryAt long Datetime of creation

Methods

run

run

///////////////////////////////////////////////////////////////
// New Experience (Enabled UniTask)
///////////////////////////////////////////////////////////////
// New Experience ではSDKレベルで実行されるため明示的にAPIを呼び出す必要はありません
// New Experience runs at the SDK level, so there is no need to explicitly call the API
///////////////////////////////////////////////////////////////
// New Experience
///////////////////////////////////////////////////////////////
// New Experience ではSDKレベルで実行されるため明示的にAPIを呼び出す必要はありません
// New Experience runs at the SDK level, so there is no need to explicitly call the API
///////////////////////////////////////////////////////////////
// Legacy Experience
///////////////////////////////////////////////////////////////

using Gs2.Core.AsyncResult;
using Gs2.Gs2Account.Unity.Result;
using Gs2.Unity.Util;

var profile = new Profile(
    clientId: "your client id",
    clientSecret: "your client secret",
    reopener: new Gs2BasicReopener()
);

{
    AsyncResult<object> asyncResult = null;
    var current = profile.Initialize(
        r => { asyncResult = r; }
    );
    yield return current;
    if (asyncResult.Error != null)
    {
        OnError(asyncResult.Error);
        yield break;
    }
}
var gs2 = new Gs2.Unity.Client(profile);

// Up to this line is the initialization process.

{
    AsyncResult<EzRunResult> asyncResult = null;
    var current = gs2.JobQueue.Run(
        callback: r => { asyncResult = r; },
        session: session,
        namespaceName: "namespace-0001"
    );

    yield return current;
    if (asyncResult.Error != null)
    {
        OnError(asyncResult.Error);
        yield break;
    }

    var result = asyncResult.Result;
    var item = result.Item;
    var result = result.Result;
    var isLastJob = result.IsLastJob;
}
// SDKレベルで実行されるため明示的にAPIを呼び出す必要はありません
// Runs at the SDK level, so there is no need to explicitly call the API
ProfilePtr = std::make_shared<gs2::ez::Profile>(
    TCHAR_TO_ANSI(*ClientId),
    TCHAR_TO_ANSI(*ClientSecret),
    gs2::ez::Gs2BasicReopener()
);

ClientPtr = std::make_shared<gs2::ez::Client>(
    *ProfilePtr
);

ProfilePtr->initialize(
    [this](gs2::ez::Profile::AsyncInitializeResult r)
    {
        if (r.getError())
        {
            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "profile.initialize failed.");
        }
        else
        {
            AccountCreate();
        }
    }
);

// Up to this line is the initialization process.

ClientPtr->jobQueue.run(
    [](gs2::ez::account::AsyncEzRunResult r)
    {
        if (r.getError())
        {
            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "jobQueue.run failed.");
        }
        else
        {
            Item = r.getResult()->getItem();
            Result = r.getResult()->getResult();
            IsLastJob = r.getResult()->getIsLastJob();
        }
    },
    ProfilePtr->getGs2Session(),
    TCHAR_TO_ANSI("namespace-0001") // namespaceName
);

Executes jobs in the task queue.

You can receive a push notification when a new job is added to the task queue by configuring the task queue push notification settings.
Call this API periodically or trigger a push notification to call this API.
Repeat as long as isLastJob returns false.



Request

Type Require Default Limitation Description
namespaceName string ~ 32 chars Namespace name
accessToken string ~ 128 chars User Id

Result

Type Description
item EzJob Job
result EzJobResultBody Job execution results
isLastJob bool

getResult

getResult

///////////////////////////////////////////////////////////////
// New Experience (Enabled UniTask)
///////////////////////////////////////////////////////////////

using Gs2.Unity.Util;
#if GS2_ENABLE_UNITASK
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
#endif

var profile = new Profile(
    clientId: "your client id",
    clientSecret: "your client secret",
    reopener: new Gs2BasicReopener()
);
await profile.InitializeAsync();
var gs2 = new Gs2.Unity.Core.Gs2Domain(profile);

// Up to this line is the initialization process.

{
    var domain = gs2.JobQueue.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Job(
        jobName: "job-0001"
    ).JobResult(
        tryNumber: null
    );
    var item = await domain.ModelAsync();
}
///////////////////////////////////////////////////////////////
// New Experience
///////////////////////////////////////////////////////////////

using Gs2.Unity.Util;

var profile = new Profile(
    clientId: "your client id",
    clientSecret: "your client secret",
    reopener: new Gs2BasicReopener()
);
var future = profile.Initialize();
yield return future;
if (future.Error != null)
{
    onError.Invoke(future.Error, null);
    yield break;
}
var gs2 = new Gs2.Unity.Core.Gs2Domain(profile);

// Up to this line is the initialization process.

{
    var domain = gs2.JobQueue.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Job(
        jobName: "job-0001"
    ).JobResult(
        tryNumber: null
    );
    var future = domain.Model();
    yield return future;
    var item = future.Result;
}
///////////////////////////////////////////////////////////////
// Legacy Experience
///////////////////////////////////////////////////////////////

using Gs2.Core.AsyncResult;
using Gs2.Gs2Account.Unity.Result;
using Gs2.Unity.Util;

var profile = new Profile(
    clientId: "your client id",
    clientSecret: "your client secret",
    reopener: new Gs2BasicReopener()
);

{
    AsyncResult<object> asyncResult = null;
    var current = profile.Initialize(
        r => { asyncResult = r; }
    );
    yield return current;
    if (asyncResult.Error != null)
    {
        OnError(asyncResult.Error);
        yield break;
    }
}
var gs2 = new Gs2.Unity.Client(profile);

// Up to this line is the initialization process.

{
    AsyncResult<EzGetResultResult> asyncResult = null;
    var current = gs2.JobQueue.GetResult(
        callback: r => { asyncResult = r; },
        session: session,
        namespaceName: "namespace-0001",
        jobName: "job-0001"
    );

    yield return current;
    if (asyncResult.Error != null)
    {
        OnError(asyncResult.Error);
        yield break;
    }

    var result = asyncResult.Result;
    var item = result.Item;
}

const auto Profile = MakeShared<Gs2::UE5::Util::FProfile>(
    "your client id",
    "your client secret",
    Gs2::Core::Model::ERegion::ApNorthEast1,
    MakeShareable<Gs2::UE5::Util::IReOpener>(new Gs2::UE5::Util::FGs2BasicReOpener())
);

Gs2::UE5::Core::Domain::FGs2DomainPtr Gs2;
{
    const auto Future = Profile->Initialize();
    Future->StartSynchronousTask();
    if (!TestFalse(WHAT, Future->GetTask().IsError())) return false;

    Gs2 = Future->GetTask().Result();
    Future->EnsureCompletion();
}

// Up to this line is the initialization process.

{
    const auto Domain = Gs2->JobQueue->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Job(
        "job-0001" // jobName
    )->JobResult(
        nullptr // tryNumber
    );
    const auto item = Domain.Model();
}
ProfilePtr = std::make_shared<gs2::ez::Profile>(
    TCHAR_TO_ANSI(*ClientId),
    TCHAR_TO_ANSI(*ClientSecret),
    gs2::ez::Gs2BasicReopener()
);

ClientPtr = std::make_shared<gs2::ez::Client>(
    *ProfilePtr
);

ProfilePtr->initialize(
    [this](gs2::ez::Profile::AsyncInitializeResult r)
    {
        if (r.getError())
        {
            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "profile.initialize failed.");
        }
        else
        {
            AccountCreate();
        }
    }
);

// Up to this line is the initialization process.

ClientPtr->jobQueue.getJobResult(
    [](gs2::ez::account::AsyncEzGetJobResultResult r)
    {
        if (r.getError())
        {
            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "jobQueue.getJobResult failed.");
        }
        else
        {
            Item = r.getResult()->getItem();
        }
    },
    ProfilePtr->getGs2Session(),
    TCHAR_TO_ANSI("namespace-0001"), // namespaceName
    TCHAR_TO_ANSI("job-0001") // jobName
);

Get Job execution result



Request

Type Require Default Limitation Description
namespaceName string ~ 32 chars Namespace name
accessToken string ~ 128 chars User Id
jobName string UUID ~ 36 chars Job Name

Result

Type Description
item EzJobResult Job execution result