cloud-game/pkg/worker/worker.go
sergystepanov 980a97a526
Handle no config situation for workers (#253)
(experimental feature)

Before a worker can start, it should have a configuration file. In case if such a file is not found it may request configuration from the coordinator to which it connected.

Added example logic if a worker is needed to be blocked until a successful packet exchange with a coordinator is being made.

* Add error return for config loader

* Add config loaded flag to worker

* Add zone flag

* Add a custom mutex lock with timout

* Refactor worker runtime

* Refactor internal api

* Extract monitoring server config

* Extract worker HTTP(S) server

* Add generic sub-server interface

* Add internal coordinator API

* Add internal routes and handlers to worker

* Add internal worker API

* Refactor worker run

* Migrate serverId call to new API

* Add packet handler to cws

* Extract handlers for internal worker routes in coordinator

* Pass worker to the worker internal heandlers

* Cleanup worker handlers in coordinator

* Add closeRoom packet handler to the API

* Add GetRoom packet handler to the API

* Add RegisterRoom packet handler to the API

* Add IceCandidate packet handler to the API (internal and browser)

* Add Heartbeat packet handler to the API (internal and browser)

* Rename worker routes init function

* Extract worker/coordinator internal ws handlers

* Update timed locker

* Allow sequential timed locks

* Add config request from workers

* Add nil check for the route registration functions
2021-01-03 21:23:55 +03:00

74 lines
1.5 KiB
Go

package worker
import (
"context"
"log"
"time"
"github.com/giongto35/cloud-game/v2/pkg/config/worker"
"github.com/giongto35/cloud-game/v2/pkg/lock"
"github.com/giongto35/cloud-game/v2/pkg/monitoring"
"github.com/giongto35/cloud-game/v2/pkg/server"
"github.com/golang/glog"
)
type Worker struct {
ctx context.Context
conf worker.Config
servers []server.Server
// to pause initialization
lock *lock.TimeLock
}
func New(ctx context.Context, conf worker.Config) *Worker {
return &Worker{ctx: ctx, conf: conf, lock: lock.NewLock()}
}
func (wrk *Worker) Run() {
go wrk.init()
wrk.servers = []server.Server{
monitoring.NewServerMonitoring(wrk.conf.Worker.Monitoring, "worker"),
}
wrk.startModules()
}
func (wrk *Worker) init() {
h := NewHandler(wrk.conf, wrk)
defer func() {
log.Printf("[worker] Closing handler")
h.Close()
}()
go h.Run()
if !wrk.conf.Loaded {
wrk.lock.LockFor(time.Second * 10)
h.RequestConfig()
}
h.Prepare()
wrk.spawnServer(wrk.conf.Worker.Server.Port)
}
func (wrk *Worker) startModules() {
glog.Info(wrk.servers)
for _, s := range wrk.servers {
s := s
go func() {
if err := s.Init(wrk.conf); err != nil {
glog.Errorf("failed server init")
return
}
if err := s.Run(); err != nil {
glog.Errorf("failed start server")
}
}()
}
}
// !to add a proper HTTP(S) server shutdown (cws/handler bad loop)
func (wrk *Worker) Shutdown() {
for _, s := range wrk.servers {
if err := s.Shutdown(wrk.ctx); err != nil {
glog.Errorln("failed server shutdown")
}
}
}