webapi: Make Run func blocking.

This updates the Run func to make it blocking. When the provided context
is canceled the server is cleanly shut down and the func returns.
This commit is contained in:
jholdstock 2023-09-15 12:04:08 +01:00 committed by Jamie Holdstock
parent 0742e0ff1a
commit f881179024
3 changed files with 22 additions and 22 deletions

View File

@ -53,9 +53,3 @@ func shutdownListener(log slog.Logger) context.Context {
}() }()
return ctx return ctx
} }
// requestShutdown signals for starting the clean shutdown of the process
// through an internal component.
func requestShutdown() {
shutdownRequestChannel <- struct{}{}
}

View File

@ -159,7 +159,12 @@ func (v *vspd) run() int {
// WaitGroup for services to signal when they have shutdown cleanly. // WaitGroup for services to signal when they have shutdown cleanly.
var shutdownWg sync.WaitGroup var shutdownWg sync.WaitGroup
api.Run(ctx, requestShutdown, &shutdownWg) // Start the webapi server.
shutdownWg.Add(1)
go func() {
api.Run(ctx)
shutdownWg.Done()
}()
// Start all background tasks and notification handlers. // Start all background tasks and notification handlers.
shutdownWg.Add(1) shutdownWg.Add(1)

View File

@ -142,10 +142,11 @@ func New(vdb *database.VspDatabase, log slog.Logger, dcrd rpc.DcrdConnect,
return w, nil return w, nil
} }
func (w *WebAPI) Run(ctx context.Context, requestShutdown func(), shutdownWg *sync.WaitGroup) { func (w *WebAPI) Run(ctx context.Context) {
var wg sync.WaitGroup
// Add the graceful shutdown to the waitgroup. // Add the graceful shutdown to the waitgroup.
shutdownWg.Add(1) wg.Add(1)
go func() { go func() {
// Wait until shutdown is signaled before shutting down. // Wait until shutdown is signaled before shutting down.
<-ctx.Done() <-ctx.Done()
@ -159,34 +160,32 @@ func (w *WebAPI) Run(ctx context.Context, requestShutdown func(), shutdownWg *sy
} else { } else {
w.log.Debug("Webserver stopped") w.log.Debug("Webserver stopped")
} }
shutdownWg.Done() wg.Done()
}() }()
// Start webserver. // Start webserver.
wg.Add(1)
go func() { go func() {
err := w.server.Serve(w.listener) err := w.server.Serve(w.listener)
// If the server dies for any reason other than ErrServerClosed (from // ErrServerClosed is expected from a graceful server shutdown, it can
// graceful server.Shutdown), log the error and request vspd be // be ignored. Anything else should be logged.
// shutdown.
if err != nil && !errors.Is(err, http.ErrServerClosed) { if err != nil && !errors.Is(err, http.ErrServerClosed) {
w.log.Errorf("Unexpected webserver error: %v", err) w.log.Errorf("Unexpected webserver error: %v", err)
requestShutdown()
} }
wg.Done()
}() }()
// Periodically update cached VSP stats. // Periodically update cached VSP stats.
var refresh time.Duration wg.Add(1)
go func() {
refresh := 1 * time.Minute
if w.cfg.Debug { if w.cfg.Debug {
refresh = 1 * time.Second refresh = 1 * time.Second
} else {
refresh = 1 * time.Minute
} }
shutdownWg.Add(1)
go func() {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
shutdownWg.Done() wg.Done()
return return
case <-time.After(refresh): case <-time.After(refresh):
err := w.cache.update() err := w.cache.update()
@ -196,6 +195,8 @@ func (w *WebAPI) Run(ctx context.Context, requestShutdown func(), shutdownWg *sy
} }
} }
}() }()
wg.Wait()
} }
func (w *WebAPI) router(cookieSecret []byte, dcrd rpc.DcrdConnect, wallets rpc.WalletConnect) *gin.Engine { func (w *WebAPI) router(cookieSecret []byte, dcrd rpc.DcrdConnect, wallets rpc.WalletConnect) *gin.Engine {