feat: runtime manager

This commit is contained in:
Ilia Denisov
2026-04-28 20:39:18 +02:00
committed by GitHub
parent e0a99b346b
commit a7cee15115
289 changed files with 45660 additions and 2207 deletions
+83 -16
View File
@@ -1,25 +1,92 @@
package ports
import "context"
import (
"context"
"fmt"
)
// StopReason classifies why Lobby asks Runtime Manager to stop a game
// container. The enum is part of the `runtime:stop_jobs` envelope and
// mirrors the AsyncAPI contract frozen in
// `rtmanager/api/runtime-jobs-asyncapi.yaml`.
//
// Lobby v1 produces only StopReasonOrphanCleanup (orphan-container path
// in the runtime-job-result worker) and StopReasonCancelled
// (user-lifecycle cascade). The remaining values are reserved in the
// shared contract for future producers (Game Master, Admin Service,
// enrollment automation).
type StopReason string
// StopReason enum values. The set is fixed by
// `rtmanager/api/runtime-jobs-asyncapi.yaml`; adding a new value is a
// contract bump that must be coordinated across producers and consumers.
const (
// StopReasonOrphanCleanup releases a container whose post-start
// metadata persistence failed in Lobby.
StopReasonOrphanCleanup StopReason = "orphan_cleanup"
// StopReasonCancelled covers user-lifecycle cascade and explicit
// cancel paths for in-flight games.
StopReasonCancelled StopReason = "cancelled"
// StopReasonFinished is reserved for engine-driven game finish
// flows; not produced by Lobby in v1.
StopReasonFinished StopReason = "finished"
// StopReasonAdminRequest is reserved for future admin-initiated
// stop paths through Lobby; not produced by Lobby in v1.
StopReasonAdminRequest StopReason = "admin_request"
// StopReasonTimeout is reserved for future enrollment-timeout-driven
// stop paths; not produced by Lobby in v1.
StopReasonTimeout StopReason = "timeout"
)
// String returns reason as its stored enum value.
func (reason StopReason) String() string {
return string(reason)
}
// Validate reports whether reason carries one of the five values fixed
// by the AsyncAPI contract.
func (reason StopReason) Validate() error {
switch reason {
case StopReasonOrphanCleanup,
StopReasonCancelled,
StopReasonFinished,
StopReasonAdminRequest,
StopReasonTimeout:
return nil
case "":
return fmt.Errorf("stop reason must not be empty")
default:
return fmt.Errorf("stop reason %q is not a recognised value", string(reason))
}
}
//go:generate go run go.uber.org/mock/mockgen -destination=../adapters/mocks/mock_runtimemanager.go -package=mocks galaxy/lobby/internal/ports RuntimeManager
// RuntimeManager publishes runtime jobs to Runtime Manager via Redis
// Streams. introduces start and stop jobs; future stages may
// extend the surface.
// Streams. Lobby is the producer for both the start and the stop stream;
// Runtime Manager (Stages 13+) is the eventual consumer.
//
// The interface is intentionally narrow: callers pass only the game id.
// Runtime Manager fetches additional context (target engine version,
// turn schedule, etc.) through Lobby's internal HTTP API when it picks
// up the job.
// Image-reference resolution is intentionally a Lobby concern: each
// game's `target_engine_version` is substituted into
// `LOBBY_ENGINE_IMAGE_TEMPLATE` and the resulting `image_ref` is handed
// to Runtime Manager verbatim on the start envelope. Runtime Manager
// never resolves engine versions itself.
type RuntimeManager interface {
// PublishStartJob enqueues one start job for gameID. Implementations
// must produce one event in the configured runtime start jobs stream
// per call. A zero-error return means the event is durably accepted
// into the stream (Redis XADD succeeded); it does not imply that the
// PublishStartJob enqueues one start job for gameID with the
// producer-resolved imageRef. Implementations must produce one
// event in the configured runtime start jobs stream per call. A
// zero-error return means the event is durably accepted into the
// stream (Redis XADD succeeded); it does not imply that the
// container has started.
PublishStartJob(ctx context.Context, gameID string) error
PublishStartJob(ctx context.Context, gameID, imageRef string) error
// PublishStopJob enqueues one stop job for gameID. Implementations
// must produce one event in the configured runtime stop jobs stream
// per call. The same durability semantics as PublishStartJob apply.
PublishStopJob(ctx context.Context, gameID string) error
// PublishStopJob enqueues one stop job for gameID with the
// classifying reason. Implementations must produce one event in the
// configured runtime stop jobs stream per call. The same durability
// semantics as PublishStartJob apply.
PublishStopJob(ctx context.Context, gameID string, reason StopReason) error
}