Files
galaxy-game/lobby/internal/ports/gmclient.go
T
2026-04-25 23:20:55 +02:00

85 lines
3.1 KiB
Go

package ports
import (
"context"
"errors"
"fmt"
"strings"
"galaxy/lobby/internal/domain/common"
)
// ErrGMUnavailable signals that a Game Master call could not be
// completed because the upstream service was unreachable, returned an
// error response, or timed out. treats every non-success
// outcome of GMClient.RegisterGame uniformly: the start flow transitions
// to `paused` and an admin notification is published.
var ErrGMUnavailable = errors.New("game master unavailable")
// GMClient executes synchronous calls to Game Master. introduced
// the registration call; added the liveness probe used by the
// voluntary resume flow.
type GMClient interface {
// RegisterGame registers a running game with Game Master after a
// successful container start and runtime binding persistence. A
// non-nil error is returned for any non-success outcome (transport
// error, timeout, non-2xx response). Implementations wrap such
// failures with ErrGMUnavailable so callers can branch with
// errors.Is.
RegisterGame(ctx context.Context, request RegisterGameRequest) error
// Ping performs a synchronous liveness probe against Game Master.
// Implementations return nil when GM is reachable and healthy and
// wrap every other outcome (transport error, timeout, non-2xx
// response) with ErrGMUnavailable so callers can
// branch with errors.Is.
Ping(ctx context.Context) error
}
// RegisterGameRequest stores the parameters required to register one
// running game with Game Master. The shape mirrors the JSON body sent
// by the HTTP adapter and is independent of the GM-side schema so the
// adapter and the consumer can reason about it without leaking
// transport details.
type RegisterGameRequest struct {
// GameID identifies the running game.
GameID common.GameID
// ContainerID identifies the engine container assigned by Runtime
// Manager.
ContainerID string
// EngineEndpoint stores the network address Game Master uses to
// reach the engine container.
EngineEndpoint string
// TargetEngineVersion stores the semver of the engine version that
// was launched (copied from the game record at registration time).
TargetEngineVersion string
// TurnSchedule stores the cron expression that drives turn
// generation (copied from the game record at registration time).
TurnSchedule string
}
// Validate reports whether request stores the structurally valid
// arguments required for Game Master registration.
func (request RegisterGameRequest) Validate() error {
if err := request.GameID.Validate(); err != nil {
return fmt.Errorf("register game: game id: %w", err)
}
if strings.TrimSpace(request.ContainerID) == "" {
return fmt.Errorf("register game: container id must not be empty")
}
if strings.TrimSpace(request.EngineEndpoint) == "" {
return fmt.Errorf("register game: engine endpoint must not be empty")
}
if strings.TrimSpace(request.TargetEngineVersion) == "" {
return fmt.Errorf("register game: target engine version must not be empty")
}
if strings.TrimSpace(request.TurnSchedule) == "" {
return fmt.Errorf("register game: turn schedule must not be empty")
}
return nil
}