diff --git a/internal/server/server.go b/internal/server/server.go index 2c4c312..90a2ef6 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -135,35 +135,45 @@ func (s *Server) Shutdown() { s.Info("starting shutdown procedure") var wg sync.WaitGroup - wg.Add(2) + wg.Add(3) go func() { defer wg.Done() - s.Info("shutting down http server") + + if err := s.world.Stop(); err != nil { + s.Error("error stopping the simulation: %v", err) + } + }() + + go func() { + defer wg.Done() + log := s.Child("http") + log.Info("shutting down http server") if err := s.http.Shutdown(context.Background()); err != nil { - s.Error("error shutting down http server: %v", err) + log.Error("error shutting down http server: %v", err) } else { - s.Info("http server has shut down") + log.Info("http server has shut down") } }() go func() { defer wg.Done() + log := s.Child("sessions") s.Lock() if len(s.sessions) > 0 { - s.Info("broadcasting shutdown to %d active sessions", len(s.sessions)) + log.Info("broadcasting shutdown to %d active sessions", len(s.sessions)) for id, sn := range s.sessions { - s.Info("sending done signal to session: %d", id) + log.Info("sending done signal to session: %d", id) sn.done <- true } } else { - s.Info("no active sessions") + log.Info("no active sessions") } s.Unlock() - s.Info("waiting on connected sessions to shut down") + log.Info("waiting on connected sessions to shut down") s.waitOnSessions.Wait() - s.Info("all sessions have shut down") + log.Info("all sessions have shut down") }() wg.Wait() s.Info("shutdown procedure complete") diff --git a/internal/sim/world.go b/internal/sim/world.go index 8706334..723f538 100644 --- a/internal/sim/world.go +++ b/internal/sim/world.go @@ -10,6 +10,7 @@ import ( type World struct { *blammo.Log rooms []room + done chan bool } func NewWorld(log *blammo.Log) *World { @@ -22,10 +23,13 @@ func NewWorld(log *blammo.Log) *World { height: 10, }, }, + done: make(chan bool), } } func (w *World) Run(hz int) { + defer w.Info("simulation has exited run loop") + period := time.Second / time.Duration(hz) w.Info("starting world with a tick rate of %dhz, frame duration of %v", hz, period) ticker := time.NewTicker(period) @@ -35,10 +39,18 @@ func (w *World) Run(hz int) { case <-ticker.C: w.tick(time.Since(lastTick)) lastTick = time.Now() + case <-w.done: + return } } } +func (w *World) Stop() error { + w.Info("stopping simulation") + w.done <- true + return nil +} + func (w *World) tick(d time.Duration) { w.Info("tick. elapsed: %v", d) }