feat: runtime manager
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user