From cf9340d5af162118ba2e1572bad28fc867cb97d7 Mon Sep 17 00:00:00 2001 From: Jamie Holdstock Date: Tue, 3 Oct 2023 10:21:00 +0100 Subject: [PATCH] Remove quit chan from Manager. Make the main loop of the Manager a blocking func which accepts a context. Shutdown the Manager when the context is canceled. This slightly alters the semantics of the code but in a way that has functionally no impact. Previously the Tickers which update the Manager would only be stopped after the HTTP server and creeper had stopped, but now they are stopped immediately when the context is canceled. --- decred.go | 9 ++++++++- manager.go | 23 +++++------------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/decred.go b/decred.go index 304aff93..08cc4f1a 100644 --- a/decred.go +++ b/decred.go @@ -159,6 +159,14 @@ func main() { amgr.AddAddresses([]netip.AddrPort{seeder}) var wg sync.WaitGroup + + wg.Add(1) + go func() { + defer wg.Done() + amgr.run(ctx) // only returns on context cancellation + log.Print("Address manager done.") + }() + wg.Add(1) go func() { defer wg.Done() @@ -177,6 +185,5 @@ func main() { // Wait for crawler and http server, then stop address manager. wg.Wait() - amgr.Stop() log.Print("Bye!") } diff --git a/manager.go b/manager.go index 72d1f2a4..46d4d67b 100644 --- a/manager.go +++ b/manager.go @@ -1,10 +1,11 @@ -// Copyright (c) 2018-2021 The Decred developers +// Copyright (c) 2018-2023 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package main import ( + "context" "encoding/json" "fmt" "log" @@ -34,8 +35,6 @@ type Manager struct { mtx sync.RWMutex nodes map[string]*Node - wg sync.WaitGroup - quit chan struct{} peersFile string } @@ -72,7 +71,6 @@ func NewManager(dataDir string) (*Manager, error) { amgr := Manager{ nodes: make(map[string]*Node), peersFile: filepath.Join(dataDir, peersFilename), - quit: make(chan struct{}), } err = amgr.deserializePeers() @@ -86,18 +84,9 @@ func NewManager(dataDir string) (*Manager, error) { } } - amgr.wg.Add(1) - go amgr.addressHandler() - return &amgr, nil } -func (m *Manager) Stop() { - close(m.quit) - m.wg.Wait() // wait for addressHandler - log.Print("Address manager done.") -} - func (m *Manager) AddAddresses(addrPorts []netip.AddrPort) int { var count int @@ -239,10 +228,8 @@ func (m *Manager) Good(addrPort netip.AddrPort, services wire.ServiceFlag, pver m.mtx.Unlock() } -// addressHandler is the main handler for the address manager. It must be run -// as a goroutine. -func (m *Manager) addressHandler() { - defer m.wg.Done() +// run is the main handler for the address manager. +func (m *Manager) run(ctx context.Context) { pruneAddressTicker := time.NewTicker(pruneAddressInterval) defer pruneAddressTicker.Stop() dumpAddressTicker := time.NewTicker(dumpAddressInterval) @@ -254,7 +241,7 @@ out: m.savePeers() case <-pruneAddressTicker.C: m.prunePeers() - case <-m.quit: + case <-ctx.Done(): break out } }