Skip to content
This repository has been archived by the owner on Nov 3, 2024. It is now read-only.

Commit

Permalink
feat: edge support
Browse files Browse the repository at this point in the history
  • Loading branch information
ZakShearman committed Sep 9, 2024
1 parent 91ac6de commit 9b3e98c
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 33 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.23
require (
agones.dev/agones v1.42.0
github.com/emortalmc/live-config-parser/golang v0.0.0-20231228020729-d2b6294e5968
github.com/emortalmc/proto-specs/gen/go v0.0.0-20231227235524-ca990cc793bf
github.com/emortalmc/proto-specs/gen/go v0.0.0-20240909151321-29fd34625282
github.com/google/uuid v1.5.0
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1
github.com/segmentio/kafka-go v0.4.47
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ github.com/emortalmc/live-config-parser/golang v0.0.0-20231228020729-d2b6294e596
github.com/emortalmc/live-config-parser/golang v0.0.0-20231228020729-d2b6294e5968/go.mod h1:CbOcbHzizWqxyflDiBKyU9LIVxZw6t5V2NlWLVfgkwY=
github.com/emortalmc/proto-specs/gen/go v0.0.0-20231227235524-ca990cc793bf h1:hAMusd3Zu4w9wJBMsNfPitbeu939vSYj1Q1x9ZrbO7U=
github.com/emortalmc/proto-specs/gen/go v0.0.0-20231227235524-ca990cc793bf/go.mod h1:se+tHcK9FWxeadkxLF5uj+SPauEye0X+Iq6cGczXGJY=
github.com/emortalmc/proto-specs/gen/go v0.0.0-20240909151212-bfb0f4305228 h1:oQxnDDw5FFkDm8qdWLRbibaijSKpIsjRuFtsg7sFcNk=
github.com/emortalmc/proto-specs/gen/go v0.0.0-20240909151212-bfb0f4305228/go.mod h1:se+tHcK9FWxeadkxLF5uj+SPauEye0X+Iq6cGczXGJY=
github.com/emortalmc/proto-specs/gen/go v0.0.0-20240909151321-29fd34625282 h1:tqF4UWZeUoC0h+nvb+mqakexuSrhEK6LGmQRep+84I0=
github.com/emortalmc/proto-specs/gen/go v0.0.0-20240909151321-29fd34625282/go.mod h1:se+tHcK9FWxeadkxLF5uj+SPauEye0X+Iq6cGczXGJY=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
Expand Down
15 changes: 11 additions & 4 deletions internal/app/kurushimi.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"github.com/emortalmc/kurushimi/internal/config"
"github.com/emortalmc/kurushimi/internal/director"
"github.com/emortalmc/kurushimi/internal/kafka"
"github.com/emortalmc/kurushimi/internal/lobbycontroller"
"github.com/emortalmc/kurushimi/internal/repository"
"github.com/emortalmc/kurushimi/internal/service"
"github.com/emortalmc/kurushimi/internal/simplecontroller"
"github.com/emortalmc/kurushimi/internal/utils/kubernetes"
"github.com/emortalmc/live-config-parser/golang/pkg/liveconfig"
"github.com/emortalmc/proto-specs/gen/go/grpc/party"
Expand Down Expand Up @@ -74,10 +74,17 @@ func Run(cfg config.Config, logger *zap.SugaredLogger) {

partyService := party.NewPartyServiceClient(pConn)

// Lobby controller
lobbyCtrl := lobbycontroller.NewLobbyController(ctx, wg, logger, cfg.Lobby, notifier, allocationClient)
// Simple controllers
lobbyCfg := cfg.Lobby
proxyCfg := cfg.Proxy

service.RunServices(ctx, logger, wg, cfg, repo, notifier, gameModeController, lobbyCtrl, partyService, partySettingsService)
lobbyCtrl := simplecontroller.NewJoinController(ctx, wg, logger, notifier, allocationClient,
lobbyCfg.FleetName, "lobby", lobbyCfg.MatchRate, lobbyCfg.MatchSize)

velocityCtrl := simplecontroller.NewJoinController(ctx, wg, logger, notifier, allocationClient,
proxyCfg.FleetName, "proxy", proxyCfg.MatchRate, proxyCfg.MatchSize)

service.RunServices(ctx, logger, wg, cfg, repo, notifier, gameModeController, lobbyCtrl, velocityCtrl, partyService, partySettingsService)

directR := director.New(logger, repo, notifier, allocationClient, gameModeController)
directR.Start(ctx)
Expand Down
26 changes: 26 additions & 0 deletions internal/config/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ const (
lobbyMatchRateFlag = "lobby-match-rate"
lobbyMatchSizeFlag = "lobby-match-size"

proxyFleetNameFlag = "proxy-fleet-name"
proxyMatchRateFlag = "proxy-match-rate"
proxyMatchSizeFlag = "proxy-match-size"

grpcPortFlag = "port"
developmentFlag = "development"
)
Expand All @@ -35,6 +39,7 @@ type Config struct {
PartyService PartyServiceConfig

Lobby LobbyConfig
Proxy ProxyConfig

Namespace string
GrpcPort int
Expand Down Expand Up @@ -64,6 +69,12 @@ type LobbyConfig struct {
MatchSize int
}

type ProxyConfig struct {
FleetName string
MatchRate time.Duration
MatchSize int
}

func LoadGlobalConfig() Config {
// Kafka
viper.SetDefault(kafkaHostFlag, "localhost")
Expand All @@ -79,6 +90,10 @@ func LoadGlobalConfig() Config {
viper.SetDefault(lobbyFleetNameFlag, "lobby")
viper.SetDefault(lobbyMatchRateFlag, 175_000_000)
viper.SetDefault(lobbyMatchSizeFlag, 50)
// Proxy
viper.SetDefault(proxyFleetNameFlag, "velocity")
viper.SetDefault(proxyMatchRateFlag, 175_000_000)
viper.SetDefault(proxyMatchSizeFlag, 50)
// Global
viper.SetDefault(namespaceFlag, "emortalmc")
viper.SetDefault(grpcPortFlag, 1007)
Expand All @@ -94,6 +109,9 @@ func LoadGlobalConfig() Config {
pflag.String(lobbyFleetNameFlag, viper.GetString(lobbyFleetNameFlag), "Lobby fleet name")
pflag.Duration(lobbyMatchRateFlag, viper.GetDuration(lobbyMatchRateFlag), "Delay between creating lobby matches")
pflag.Int32(lobbyMatchSizeFlag, viper.GetInt32(lobbyMatchSizeFlag), "Maximum size of a lobby (accounts for players already in the lobby)")
pflag.String(proxyFleetNameFlag, viper.GetString(proxyFleetNameFlag), "Proxy fleet name (default velocity)")
pflag.Duration(proxyMatchRateFlag, viper.GetDuration(proxyMatchRateFlag), "Delay between creating proxy matches")
pflag.Int32(proxyMatchSizeFlag, viper.GetInt32(proxyMatchSizeFlag), "Maximum size of a proxy (accounts for players already in the proxy)")
pflag.String(namespaceFlag, viper.GetString(namespaceFlag), "Namespace that the resource is in")
pflag.Int32(grpcPortFlag, viper.GetInt32(grpcPortFlag), "gRPC port of THIS service")
pflag.Bool(developmentFlag, viper.GetBool(developmentFlag), "Development mode")
Expand All @@ -111,6 +129,9 @@ func LoadGlobalConfig() Config {
runtime.Must(viper.BindEnv(lobbyFleetNameFlag))
runtime.Must(viper.BindEnv(lobbyMatchRateFlag))
runtime.Must(viper.BindEnv(lobbyMatchSizeFlag))
runtime.Must(viper.BindEnv(proxyFleetNameFlag))
runtime.Must(viper.BindEnv(proxyMatchRateFlag))
runtime.Must(viper.BindEnv(proxyMatchSizeFlag))
runtime.Must(viper.BindEnv(namespaceFlag))
runtime.Must(viper.BindEnv(grpcPortFlag))
runtime.Must(viper.BindEnv(developmentFlag))
Expand All @@ -134,6 +155,11 @@ func LoadGlobalConfig() Config {
MatchRate: viper.GetDuration(lobbyMatchRateFlag),
MatchSize: int(viper.GetInt32(lobbyMatchSizeFlag)),
},
Proxy: ProxyConfig{
FleetName: viper.GetString(proxyFleetNameFlag),
MatchRate: viper.GetDuration(proxyMatchRateFlag),
MatchSize: int(viper.GetInt32(proxyMatchSizeFlag)),
},
Namespace: viper.GetString(namespaceFlag),
GrpcPort: int(viper.GetInt32(grpcPortFlag)),
Development: viper.GetBool(developmentFlag),
Expand Down
21 changes: 14 additions & 7 deletions internal/service/matchmaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"context"
"fmt"
"github.com/emortalmc/kurushimi/internal/kafka"
"github.com/emortalmc/kurushimi/internal/lobbycontroller"
"github.com/emortalmc/kurushimi/internal/repository"
"github.com/emortalmc/kurushimi/internal/repository/model"
"github.com/emortalmc/kurushimi/internal/simplecontroller"
"github.com/emortalmc/live-config-parser/golang/pkg/liveconfig"
"github.com/emortalmc/proto-specs/gen/go/grpc/matchmaker"
pbparty "github.com/emortalmc/proto-specs/gen/go/grpc/party"
Expand All @@ -29,14 +29,16 @@ type matchmakerService struct {
notifier kafka.Notifier
cfgController liveconfig.GameModeConfigController

lobbyController lobbycontroller.LobbyController
lobbyController simplecontroller.SimpleController
velocityController simplecontroller.SimpleController

partyService pbparty.PartyServiceClient
partySettingsService pbparty.PartySettingsServiceClient
}

func newMatchmakerService(logger *zap.SugaredLogger, repository repository.Repository, notifier kafka.Notifier,
cfgController liveconfig.GameModeConfigController, lobbyController lobbycontroller.LobbyController,
cfgController liveconfig.GameModeConfigController, lobbyController simplecontroller.SimpleController,
velocityController simplecontroller.SimpleController,
partyService pbparty.PartyServiceClient, partySettingsService pbparty.PartySettingsServiceClient) matchmaker.MatchmakerServer {

return &matchmakerService{
Expand All @@ -45,7 +47,8 @@ func newMatchmakerService(logger *zap.SugaredLogger, repository repository.Repos
notifier: notifier,
cfgController: cfgController,

lobbyController: lobbyController,
lobbyController: lobbyController,
velocityController: velocityController,

partyService: partyService,
partySettingsService: partySettingsService,
Expand Down Expand Up @@ -284,15 +287,19 @@ func (m *matchmakerService) SendPlayersToLobby(ctx context.Context, request *mat
return &matchmaker.SendPlayerToLobbyResponse{}, nil
}

func (m *matchmakerService) QueueInitialLobbyByPlayer(_ context.Context, request *matchmaker.QueueInitialLobbyByPlayerRequest) (*matchmaker.QueueInitialLobbyByPlayerResponse, error) {
func (m *matchmakerService) LoginQueueByPlayer(_ context.Context, request *matchmaker.LoginQueueByPlayerRequest) (*matchmaker.LoginQueueByPlayerResponse, error) {
playerId, err := uuid.Parse(request.PlayerId)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid player_id")
}

m.lobbyController.QueuePlayer(playerId, false)
if !request.IsProxy {
m.lobbyController.QueuePlayer(playerId, false)
} else {
m.velocityController.QueuePlayer(playerId, false)
}

return &matchmaker.QueueInitialLobbyByPlayerResponse{}, nil
return &matchmaker.LoginQueueByPlayerResponse{}, nil
}

var (
Expand Down
8 changes: 4 additions & 4 deletions internal/service/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"fmt"
"github.com/emortalmc/kurushimi/internal/config"
"github.com/emortalmc/kurushimi/internal/kafka"
"github.com/emortalmc/kurushimi/internal/lobbycontroller"
"github.com/emortalmc/kurushimi/internal/repository"
"github.com/emortalmc/kurushimi/internal/simplecontroller"
"github.com/emortalmc/kurushimi/internal/utils/grpczap"
"github.com/emortalmc/live-config-parser/golang/pkg/liveconfig"
"github.com/emortalmc/proto-specs/gen/go/grpc/matchmaker"
Expand All @@ -21,8 +21,8 @@ import (

func RunServices(ctx context.Context, logger *zap.SugaredLogger, wg *sync.WaitGroup, cfg config.Config,
repo repository.Repository, notifier kafka.Notifier, gameModeController liveconfig.GameModeConfigController,
lobbyCtrl lobbycontroller.LobbyController, partyService party.PartyServiceClient,
partySettingsService party.PartySettingsServiceClient) {
lobbyCtrl simplecontroller.SimpleController, velocityCtrl simplecontroller.SimpleController,
partyService party.PartyServiceClient, partySettingsService party.PartySettingsServiceClient) {

lis, err := net.Listen("tcp", fmt.Sprintf(":%d", cfg.GrpcPort))
if err != nil {
Expand All @@ -43,7 +43,7 @@ func RunServices(ctx context.Context, logger *zap.SugaredLogger, wg *sync.WaitGr
}

matchmaker.RegisterMatchmakerServer(s, newMatchmakerService(logger, repo, notifier, gameModeController, lobbyCtrl,
partyService, partySettingsService))
velocityCtrl, partyService, partySettingsService))
logger.Infow("listening for gRPC requests", "port", cfg.GrpcPort)

go func() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package lobbycontroller
package simplecontroller

import (
v13 "agones.dev/agones/pkg/apis/allocation/v1"
v1 "agones.dev/agones/pkg/client/clientset/versioned/typed/allocation/v1"
"context"
"github.com/emortalmc/kurushimi/internal/config"
"github.com/emortalmc/kurushimi/internal/gsallocation"
"github.com/emortalmc/kurushimi/internal/gsallocation/selector"
"github.com/emortalmc/kurushimi/internal/kafka"
Expand All @@ -17,12 +16,15 @@ import (
"time"
)

type LobbyController interface {
// SimpleController is a controller to allocate players into matches for simple servers - not gamemodes.
// It is necessary due to Agones behaviours we want to work around for lobbies and proxies.
type SimpleController interface {
QueuePlayer(playerId uuid.UUID, autoTeleport bool)
}

type lobbyControllerImpl struct {
type simpleControllerImpl struct {
fleetName string
gameModeId string
matchmakingRate time.Duration
playersPerMatch int

Expand All @@ -35,13 +37,15 @@ type lobbyControllerImpl struct {
queuedPlayersLock sync.Mutex
}

func NewLobbyController(ctx context.Context, wg *sync.WaitGroup, logger *zap.SugaredLogger, cfg config.LobbyConfig, notifier kafka.Notifier,
allocatorClient v1.GameServerAllocationInterface) LobbyController {
func NewJoinController(ctx context.Context, wg *sync.WaitGroup, logger *zap.SugaredLogger, notifier kafka.Notifier,
allocatorClient v1.GameServerAllocationInterface, fleetName string, gameModeID string, matchRate time.Duration,
playersPerMatch int) SimpleController {

c := &lobbyControllerImpl{
fleetName: cfg.FleetName,
matchmakingRate: cfg.MatchRate,
playersPerMatch: cfg.MatchSize,
c := &simpleControllerImpl{
fleetName: fleetName,
gameModeId: gameModeID,
matchmakingRate: matchRate,
playersPerMatch: playersPerMatch,

logger: logger,
notifier: notifier,
Expand All @@ -56,14 +60,14 @@ func NewLobbyController(ctx context.Context, wg *sync.WaitGroup, logger *zap.Sug
return c
}

func (l *lobbyControllerImpl) QueuePlayer(playerId uuid.UUID, autoTeleport bool) {
func (l *simpleControllerImpl) QueuePlayer(playerId uuid.UUID, autoTeleport bool) {
l.queuedPlayersLock.Lock()
defer l.queuedPlayersLock.Unlock()

l.queuedPlayers[playerId] = autoTeleport
}

func (l *lobbyControllerImpl) run(wg *sync.WaitGroup, ctx context.Context) {
func (l *simpleControllerImpl) run(wg *sync.WaitGroup, ctx context.Context) {
go func() {
for {
if ctx.Err() != nil {
Expand Down Expand Up @@ -100,7 +104,7 @@ func (l *lobbyControllerImpl) run(wg *sync.WaitGroup, ctx context.Context) {
}()
}

func (l *lobbyControllerImpl) resetQueuedPlayers() map[uuid.UUID]bool {
func (l *simpleControllerImpl) resetQueuedPlayers() map[uuid.UUID]bool {
l.queuedPlayersLock.Lock()
defer l.queuedPlayersLock.Unlock()

Expand All @@ -114,7 +118,7 @@ func (l *lobbyControllerImpl) resetQueuedPlayers() map[uuid.UUID]bool {
return queuedPlayers
}

func (l *lobbyControllerImpl) createMatchesFromPlayers(playerMap map[uuid.UUID]bool) map[*pb.Match]*v13.GameServerAllocation {
func (l *simpleControllerImpl) createMatchesFromPlayers(playerMap map[uuid.UUID]bool) map[*pb.Match]*v13.GameServerAllocation {
allocationReqs := make(map[*pb.Match]*v13.GameServerAllocation)

if len(playerMap) > 0 {
Expand All @@ -123,7 +127,7 @@ func (l *lobbyControllerImpl) createMatchesFromPlayers(playerMap map[uuid.UUID]b

currentMatch := &pb.Match{
Id: primitive.NewObjectID().String(),
GameModeId: "lobby",
GameModeId: l.gameModeId,
MapId: nil,
Tickets: make([]*pb.Ticket, 0),
Assignment: nil,
Expand All @@ -134,7 +138,7 @@ func (l *lobbyControllerImpl) createMatchesFromPlayers(playerMap map[uuid.UUID]b
currentMatch.Tickets = append(currentMatch.Tickets, &pb.Ticket{
PlayerIds: []string{playerId.String()},
CreatedAt: timestamppb.Now(),
GameModeId: "lobby",
GameModeId: l.gameModeId,
AutoTeleport: autoTeleport,
DequeueOnDisconnect: false,
InPendingMatch: false,
Expand All @@ -145,7 +149,7 @@ func (l *lobbyControllerImpl) createMatchesFromPlayers(playerMap map[uuid.UUID]b
allocationReqs[currentMatch] = selector.CreatePlayerBasedSelector(l.fleetName, currentMatch, int64(currentCount))
currentMatch = &pb.Match{
Id: primitive.NewObjectID().Hex(),
GameModeId: "lobby",
GameModeId: l.gameModeId,
MapId: nil,
Tickets: make([]*pb.Ticket, 0),
Assignment: nil,
Expand Down

0 comments on commit 9b3e98c

Please sign in to comment.