227 lines
7.4 KiB
YAML
227 lines
7.4 KiB
YAML
asyncapi: 3.1.0
|
|
info:
|
|
title: Galaxy Runtime Jobs Stream Contract
|
|
version: 1.0.0
|
|
description: |
|
|
Stable Redis Streams contract carrying runtime jobs between
|
|
`Game Lobby` and `Runtime Manager`.
|
|
|
|
`Game Lobby` is the sole producer for `runtime:start_jobs` and
|
|
`runtime:stop_jobs`. `Runtime Manager` consumes both, executes the
|
|
Docker work, and publishes one outcome per job to `runtime:job_results`,
|
|
which is consumed by `Game Lobby`'s runtime-job-result worker.
|
|
|
|
Replay safety:
|
|
- duplicate start jobs for an already-running game with the same
|
|
`image_ref` produce a `success` job result with
|
|
`error_code=replay_no_op`;
|
|
- duplicate stop jobs for an already-stopped or already-removed game
|
|
produce a `success` job result with `error_code=replay_no_op`.
|
|
|
|
The `reason` enum on `runtime:stop_jobs` is fixed in this contract.
|
|
Adding a new value requires a contract bump and a coordinated
|
|
Lobby/Runtime Manager change.
|
|
channels:
|
|
startJobs:
|
|
address: runtime:start_jobs
|
|
messages:
|
|
runtimeStartJob:
|
|
$ref: '#/components/messages/RuntimeStartJob'
|
|
stopJobs:
|
|
address: runtime:stop_jobs
|
|
messages:
|
|
runtimeStopJob:
|
|
$ref: '#/components/messages/RuntimeStopJob'
|
|
jobResults:
|
|
address: runtime:job_results
|
|
messages:
|
|
runtimeJobResult:
|
|
$ref: '#/components/messages/RuntimeJobResult'
|
|
operations:
|
|
consumeStartJob:
|
|
action: receive
|
|
summary: Receive one start job from Game Lobby and run a container.
|
|
channel:
|
|
$ref: '#/channels/startJobs'
|
|
messages:
|
|
- $ref: '#/channels/startJobs/messages/runtimeStartJob'
|
|
consumeStopJob:
|
|
action: receive
|
|
summary: Receive one stop job from Game Lobby and stop a container.
|
|
channel:
|
|
$ref: '#/channels/stopJobs'
|
|
messages:
|
|
- $ref: '#/channels/stopJobs/messages/runtimeStopJob'
|
|
publishJobResult:
|
|
action: send
|
|
summary: Publish one runtime job outcome for Game Lobby.
|
|
channel:
|
|
$ref: '#/channels/jobResults'
|
|
messages:
|
|
- $ref: '#/channels/jobResults/messages/runtimeJobResult'
|
|
components:
|
|
messages:
|
|
RuntimeStartJob:
|
|
name: RuntimeStartJob
|
|
title: Runtime start job
|
|
summary: Lobby request to start one game engine container.
|
|
payload:
|
|
$ref: '#/components/schemas/RuntimeStartJobPayload'
|
|
examples:
|
|
- name: startJob
|
|
summary: Start a game engine container with a producer-resolved image_ref.
|
|
payload:
|
|
game_id: game-123
|
|
image_ref: registry.example.com/galaxy/game:1.4.7
|
|
requested_at_ms: 1775121700000
|
|
RuntimeStopJob:
|
|
name: RuntimeStopJob
|
|
title: Runtime stop job
|
|
summary: Lobby request to stop one game engine container.
|
|
payload:
|
|
$ref: '#/components/schemas/RuntimeStopJobPayload'
|
|
examples:
|
|
- name: cancelled
|
|
summary: Stop the engine because the game was cancelled.
|
|
payload:
|
|
game_id: game-123
|
|
reason: cancelled
|
|
requested_at_ms: 1775121800000
|
|
- name: orphanCleanup
|
|
summary: Stop an engine whose Lobby metadata persistence failed.
|
|
payload:
|
|
game_id: game-456
|
|
reason: orphan_cleanup
|
|
requested_at_ms: 1775121810000
|
|
RuntimeJobResult:
|
|
name: RuntimeJobResult
|
|
title: Runtime job result
|
|
summary: Outcome of one start or stop job.
|
|
payload:
|
|
$ref: '#/components/schemas/RuntimeJobResultPayload'
|
|
examples:
|
|
- name: startSuccess
|
|
summary: Successful start, container_id and engine_endpoint are populated.
|
|
payload:
|
|
game_id: game-123
|
|
outcome: success
|
|
container_id: 7c2b5d1a4f6e
|
|
engine_endpoint: http://galaxy-game-game-123:8080
|
|
error_code: ""
|
|
error_message: ""
|
|
- name: imagePullFailed
|
|
summary: Failed start due to an image pull error.
|
|
payload:
|
|
game_id: game-789
|
|
outcome: failure
|
|
container_id: ""
|
|
engine_endpoint: ""
|
|
error_code: image_pull_failed
|
|
error_message: "manifest unknown"
|
|
- name: replayNoOp
|
|
summary: Idempotent replay; the job was a no-op.
|
|
payload:
|
|
game_id: game-123
|
|
outcome: success
|
|
container_id: 7c2b5d1a4f6e
|
|
engine_endpoint: http://galaxy-game-game-123:8080
|
|
error_code: replay_no_op
|
|
error_message: ""
|
|
schemas:
|
|
RuntimeStartJobPayload:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- game_id
|
|
- image_ref
|
|
- requested_at_ms
|
|
properties:
|
|
game_id:
|
|
type: string
|
|
description: Opaque stable game identifier owned by Lobby.
|
|
image_ref:
|
|
type: string
|
|
description: Docker reference resolved by Lobby from LOBBY_ENGINE_IMAGE_TEMPLATE.
|
|
requested_at_ms:
|
|
type: integer
|
|
format: int64
|
|
description: UTC milliseconds; used for diagnostics, not authoritative.
|
|
RuntimeStopJobPayload:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- game_id
|
|
- reason
|
|
- requested_at_ms
|
|
properties:
|
|
game_id:
|
|
type: string
|
|
description: Opaque stable game identifier owned by Lobby.
|
|
reason:
|
|
$ref: '#/components/schemas/StopReason'
|
|
requested_at_ms:
|
|
type: integer
|
|
format: int64
|
|
description: UTC milliseconds; used for diagnostics, not authoritative.
|
|
RuntimeJobResultPayload:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- game_id
|
|
- outcome
|
|
- container_id
|
|
- engine_endpoint
|
|
- error_code
|
|
- error_message
|
|
properties:
|
|
game_id:
|
|
type: string
|
|
description: Opaque stable game identifier matching the originating job.
|
|
outcome:
|
|
type: string
|
|
enum:
|
|
- success
|
|
- failure
|
|
description: High-level outcome of the runtime job.
|
|
container_id:
|
|
type: string
|
|
description: Docker container id of the engine; populated on success, empty on failure.
|
|
engine_endpoint:
|
|
type: string
|
|
description: Stable engine URL `http://galaxy-game-{game_id}:8080`; populated on success, empty on failure.
|
|
error_code:
|
|
$ref: '#/components/schemas/ErrorCode'
|
|
error_message:
|
|
type: string
|
|
description: Operator-readable detail; empty when not applicable.
|
|
StopReason:
|
|
type: string
|
|
enum:
|
|
- orphan_cleanup
|
|
- cancelled
|
|
- finished
|
|
- admin_request
|
|
- timeout
|
|
description: Reason value carried by every runtime:stop_jobs envelope.
|
|
ErrorCode:
|
|
type: string
|
|
enum:
|
|
- ""
|
|
- invalid_request
|
|
- not_found
|
|
- conflict
|
|
- service_unavailable
|
|
- internal_error
|
|
- image_pull_failed
|
|
- image_ref_not_semver
|
|
- semver_patch_only
|
|
- container_start_failed
|
|
- start_config_invalid
|
|
- docker_unavailable
|
|
- replay_no_op
|
|
description: |
|
|
Stable error code identical to the internal REST contract. The empty
|
|
string is a valid value for successful job results that did not
|
|
produce a code (the field is required to be present so consumers
|
|
can rely on the schema).
|