Repository: ipfs/go-bitswap
Pull request #78 (2019-02-20 22:58:52)

make the WantlistManager own the PeerHandler
And remove all locks.


Patch:
diff --git a/bitswap.go b/bitswap.go
index 217d544..87418a9 100644
--- a/bitswap.go
+++ b/bitswap.go
@@ -102,7 +102,7 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
 		return bsmq.New(ctx, p, network)
 	}
 
-	wm := bswm.New(ctx)
+	wm := bswm.New(ctx, bspm.New(ctx, peerQueueFactory))
 	pqm := bspqm.New(ctx, network)
 
 	sessionFactory := func(ctx context.Context, id uint64, pm bssession.PeerManager, srs bssession.RequestSplitter) bssm.Session {
@@ -124,7 +124,6 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
 		provideKeys:   make(chan cid.Cid, provideKeysBufferSize),
 		wm:            wm,
 		pqm:           pqm,
-		pm:            bspm.New(ctx, peerQueueFactory),
 		sm:            bssm.New(ctx, sessionFactory, sessionPeerManagerFactory, sessionRequestSplitterFactory),
 		counters:      new(counters),
 		dupMetric:     dupHist,
@@ -132,7 +131,6 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
 		sentHistogram: sentHistogram,
 	}
 
-	bs.wm.SetDelegate(bs.pm)
 	bs.wm.Startup()
 	bs.pqm.Startup()
 	network.SetDelegate(bs)
@@ -153,10 +151,6 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
 
 // Bitswap instances implement the bitswap protocol.
 type Bitswap struct {
-	// the peermanager manages sending messages to peers in a way that
-	// wont block bitswap operation
-	pm *bspm.PeerManager
-
 	// the wantlist tracks global wants for bitswap
 	wm *bswm.WantManager
 
diff --git a/peermanager/peermanager.go b/peermanager/peermanager.go
index 59e8ca3..51cdf27 100644
--- a/peermanager/peermanager.go
+++ b/peermanager/peermanager.go
@@ -2,7 +2,6 @@ package peermanager
 
 import (
 	"context"
-	"sync"
 
 	bsmsg "github.com/ipfs/go-bitswap/message"
 	wantlist "github.com/ipfs/go-bitswap/wantlist"
@@ -40,8 +39,7 @@ type peerQueueInstance struct {
 // PeerManager manages a pool of peers and sends messages to peers in the pool.
 type PeerManager struct {
 	// peerQueues -- interact through internal utility functions get/set/remove/iterate
-	peerQueues   map[peer.ID]*peerQueueInstance
-	peerQueuesLk sync.RWMutex
+	peerQueues map[peer.ID]*peerQueueInstance
 
 	createPeerQueue PeerQueueFactory
 	ctx             context.Context
@@ -58,8 +56,6 @@ func New(ctx context.Context, createPeerQueue PeerQueueFactory) *PeerManager {
 
 // ConnectedPeers returns a list of peers this PeerManager is managing.
 func (pm *PeerManager) ConnectedPeers() []peer.ID {
-	pm.peerQueuesLk.RLock()
-	defer pm.peerQueuesLk.RUnlock()
 	peers := make([]peer.ID, 0, len(pm.peerQueues))
 	for p := range pm.peerQueues {
 		peers = append(peers, p)
@@ -70,8 +66,6 @@ func (pm *PeerManager) ConnectedPeers() []peer.ID {
 // Connected is called to add a new peer to the pool, and send it an initial set
 // of wants.
 func (pm *PeerManager) Connected(p peer.ID, initialWants *wantlist.SessionTrackedWantlist) {
-	pm.peerQueuesLk.Lock()
-
 	pq := pm.getOrCreate(p)
 
 	if pq.refcnt == 0 {
@@ -79,47 +73,35 @@ func (pm *PeerManager) Connected(p peer.ID, initialWants *wantlist.SessionTracke
 	}
 
 	pq.refcnt++
-
-	pm.peerQueuesLk.Unlock()
 }
 
 // Disconnected is called to remove a peer from the pool.
 func (pm *PeerManager) Disconnected(p peer.ID) {
-	pm.peerQueuesLk.Lock()
 	pq, ok := pm.peerQueues[p]
 
 	if !ok {
-		pm.peerQueuesLk.Unlock()
 		return
 	}
 
 	pq.refcnt--
 	if pq.refcnt > 0 {
-		pm.peerQueuesLk.Unlock()
 		return
 	}
 
 	delete(pm.peerQueues, p)
-	pm.peerQueuesLk.Unlock()
-
 	pq.pq.Shutdown()
-
 }
 
 // SendMessage is called to send a message to all or some peers in the pool;
 // if targets is nil, it sends to all.
 func (pm *PeerManager) SendMessage(entries []bsmsg.Entry, targets []peer.ID, from uint64) {
 	if len(targets) == 0 {
-		pm.peerQueuesLk.RLock()
 		for _, p := range pm.peerQueues {
 			p.pq.AddMessage(entries, from)
 		}
-		pm.peerQueuesLk.RUnlock()
 	} else {
 		for _, t := range targets {
-			pm.peerQueuesLk.Lock()
 			pqi := pm.getOrCreate(t)
-			pm.peerQueuesLk.Unlock()
 			pqi.pq.AddMessage(entries, from)
 		}
 	}
diff --git a/wantmanager/wantmanager.go b/wantmanager/wantmanager.go
index 0fd7d5a..5f11294 100644
--- a/wantmanager/wantmanager.go
+++ b/wantmanager/wantmanager.go
@@ -53,7 +53,7 @@ type WantManager struct {
 }
 
 // New initializes a new WantManager for a given context.
-func New(ctx context.Context) *WantManager {
+func New(ctx context.Context, peerHandler PeerHandler) *WantManager {
 	ctx, cancel := context.WithCancel(ctx)
 	wantlistGauge := metrics.NewCtx(ctx, "wantlist_total",
 		"Number of items in wantlist.").Gauge()
@@ -63,15 +63,11 @@ func New(ctx context.Context) *WantManager {
 		bcwl:          wantlist.NewSessionTrackedWantlist(),
 		ctx:           ctx,
 		cancel:        cancel,
+		peerHandler:   peerHandler,
 		wantlistGauge: wantlistGauge,
 	}
 }
 
-// SetDelegate specifies who will send want changes out to the internet.
-func (wm *WantManager) SetDelegate(peerHandler PeerHandler) {
-	wm.peerHandler = peerHandler
-}
-
 // WantBlocks adds the given cids to the wantlist, tracked by the given session.
 func (wm *WantManager) WantBlocks(ctx context.Context, ks []cid.Cid, peers []peer.ID, ses uint64) {
 	log.Infof("want blocks: %s", ks)


Test patch:
diff --git a/bitswap_test.go b/bitswap_test.go
index 6b0f5c7..bbd1b34 100644
--- a/bitswap_test.go
+++ b/bitswap_test.go
@@ -199,19 +199,6 @@ func PerformDistributionTest(t *testing.T, numInstances, numBlocks int) {
 
 	t.Log("Give the blocks to the first instance")
 
-	nump := len(instances) - 1
-	// assert we're properly connected
-	for _, inst := range instances {
-		peers := inst.Exchange.pm.ConnectedPeers()
-		for i := 0; i < 10 && len(peers) != nump; i++ {
-			time.Sleep(time.Millisecond * 50)
-			peers = inst.Exchange.pm.ConnectedPeers()
-		}
-		if len(peers) != nump {
-			t.Fatal("not enough peers connected to instance")
-		}
-	}
-
 	var blkeys []cid.Cid
 	first := instances[0]
 	for _, b := range blocks {
diff --git a/wantmanager/wantmanager_test.go b/wantmanager/wantmanager_test.go
index 3b9d0cb..0369082 100644
--- a/wantmanager/wantmanager_test.go
+++ b/wantmanager/wantmanager_test.go
@@ -40,7 +40,7 @@ func setupTestFixturesAndInitialWantList() (
 
 	// setup fixtures
 	wantSender := &fakePeerHandler{}
-	wantManager := New(ctx)
+	wantManager := New(ctx, wantSender)
 	keys := testutil.GenerateCids(10)
 	otherKeys := testutil.GenerateCids(5)
 	peers := testutil.GeneratePeers(10)
@@ -48,7 +48,6 @@ func setupTestFixturesAndInitialWantList() (
 	otherSession := testutil.GenerateSessionID()
 
 	// startup wantManager
-	wantManager.SetDelegate(wantSender)
 	wantManager.Startup()
 
 	// add initial wants