From 10d1b2c5613b1985d67ad31ccd4d236e7891dfe1 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 21 Oct 2021 12:12:37 -0700 Subject: [PATCH] fix: reduce receive contention This means we need to frequently re-take this lock, but it also means we don't hold it while calling other functions that might block (e.g., while pushing jobs). --- internal/decision/engine.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/decision/engine.go b/internal/decision/engine.go index df49f0bc..ea7e9db0 100644 --- a/internal/decision/engine.go +++ b/internal/decision/engine.go @@ -673,12 +673,18 @@ func (e *Engine) ReceiveFrom(from peer.ID, blks []blocks.Block) { // Check each peer to see if it wants one of the blocks we received var work bool missingWants := make(map[peer.ID][]cid.Cid) - e.lock.RLock() for _, b := range blks { k := b.Cid() - for _, p := range e.peerLedger.Peers(k) { + e.lock.RLock() + peers := e.peerLedger.Peers(k) + e.lock.RUnlock() + + for _, p := range peers { + e.lock.RLock() ledger, ok := e.ledgerMap[p] + e.lock.RUnlock() + if !ok { // This can happen if the peer has disconnected while we're processing this list. log.Debugw("failed to find peer in ledger", "peer", p) @@ -718,7 +724,6 @@ func (e *Engine) ReceiveFrom(from peer.ID, blks []blocks.Block) { e.updateMetrics() } } - e.lock.RUnlock() // If we found missing wants (e.g., because the peer disconnected, we have some races here) // remove them from the list. Unfortunately, we still have to re-check because the user