From 9bed07a5c93b3be6c9aa2d97dafce1e163f9d7e9 Mon Sep 17 00:00:00 2001 From: Pavel Zbitskiy Date: Tue, 5 Aug 2025 13:06:54 -0400 Subject: [PATCH] network: fix mesher stopping logic Originally Mesher relied on a supplied context to handle termination so network's context supposed to be canceled first. wsNetwork's meshThreadInner executes tryConnect asynchronously so that calling it directly from Mesher after possible network termination ends up with tryConnect goroutine still running. --- network/hybridNetwork.go | 3 ++- network/mesh.go | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/network/hybridNetwork.go b/network/hybridNetwork.go index 57ef3bd078..1f2545b149 100644 --- a/network/hybridNetwork.go +++ b/network/hybridNetwork.go @@ -212,12 +212,13 @@ func (n *HybridP2PNetwork) Start() error { // Stop implements GossipNode func (n *HybridP2PNetwork) Stop() { + n.mesher.stop() + _ = n.runParallel(func(net GossipNode) error { net.Stop() return nil }) - n.mesher.stop() } // RegisterHandlers adds to the set of given message handlers. diff --git a/network/mesh.go b/network/mesh.go index 7b020c610a..6a1cdfb6d2 100644 --- a/network/mesh.go +++ b/network/mesh.go @@ -35,12 +35,14 @@ type mesher interface { } type baseMesher struct { - wg sync.WaitGroup + wg sync.WaitGroup + ctx context.Context + cancel context.CancelFunc meshConfig } type meshConfig struct { - ctx context.Context + parentCtx context.Context meshUpdateRequests chan meshRequest meshThreadInterval time.Duration backoff backoff.BackoffStrategy @@ -96,7 +98,7 @@ func withMeshUpdateInterval(d time.Duration) meshOption { func withContext(ctx context.Context) meshOption { return func(cfg *meshConfig) { - cfg.ctx = ctx + cfg.parentCtx = ctx } } @@ -117,7 +119,7 @@ func newBaseMesher(opts ...meshOption) (*baseMesher, error) { for _, opt := range opts { opt(&cfg) } - if cfg.ctx == nil { + if cfg.parentCtx == nil { return nil, errors.New("context is not set") } if cfg.netMeshFn == nil { @@ -130,7 +132,10 @@ func newBaseMesher(opts ...meshOption) (*baseMesher, error) { cfg.meshThreadInterval = meshThreadInterval } + ctx, cancel := context.WithCancel(cfg.parentCtx) return &baseMesher{ + ctx: ctx, + cancel: cancel, meshConfig: cfg, }, nil } @@ -178,6 +183,7 @@ func (m *baseMesher) start() { } func (m *baseMesher) stop() { + m.cancel() m.wg.Wait() if m.closer != nil { m.closer()