Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion network/hybridNetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 10 additions & 4 deletions network/mesh.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}

Expand All @@ -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 {
Expand All @@ -130,7 +132,10 @@ func newBaseMesher(opts ...meshOption) (*baseMesher, error) {
cfg.meshThreadInterval = meshThreadInterval
}

ctx, cancel := context.WithCancel(cfg.parentCtx)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious, why make a child context and cancel it in baseMesher.stop() if the parent context will be cancelled by the network upstream? or is the issue that for hybridNetwork there is no WithContext() being passed or something

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the issue with hybrid is the following (in the original code):

  1. Stoping wsNet and then the mesher
  2. In between wsNet.Stop() and mesher.stop() mesher's goroutine calls directly meshThreadInner that spawns a goroutine for tryConnect
  3. Since wsNet.Stop() has already executed, nothing checks for tryConnect wait group and the goroutine still alive when the main thread exits.

return &baseMesher{
ctx: ctx,
cancel: cancel,
meshConfig: cfg,
}, nil
}
Expand Down Expand Up @@ -178,6 +183,7 @@ func (m *baseMesher) start() {
}

func (m *baseMesher) stop() {
m.cancel()
m.wg.Wait()
if m.closer != nil {
m.closer()
Expand Down
Loading