87 lines
3.2 KiB
Go
87 lines
3.2 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")
|
|
|
|
//go:generate go run go.uber.org/mock/mockgen -destination=../adapters/mocks/mock_gmclient.go -package=mocks galaxy/lobby/internal/ports GMClient
|
|
|
|
// 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
|
|
}
|