Skip to content

Commit 2a5234f

Browse files
authored
Merge pull request ipfs/go-bitswap#374 from ipfs/refactor/unref-want-mgr
refactor: remove WantManager This commit was moved from ipfs/go-bitswap@5643004
2 parents b4ce47b + 8d0dcda commit 2a5234f

12 files changed

+156
-343
lines changed

bitswap/bitswap.go

+9-16
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
bssim "github.com/ipfs/go-bitswap/internal/sessioninterestmanager"
2323
bssm "github.com/ipfs/go-bitswap/internal/sessionmanager"
2424
bsspm "github.com/ipfs/go-bitswap/internal/sessionpeermanager"
25-
bswm "github.com/ipfs/go-bitswap/internal/wantmanager"
2625
bsmsg "github.com/ipfs/go-bitswap/message"
2726
bsnet "github.com/ipfs/go-bitswap/network"
2827
blocks "github.com/ipfs/go-block-format"
@@ -123,13 +122,13 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
123122
return nil
124123
})
125124

126-
var wm *bswm.WantManager
127125
// onDontHaveTimeout is called when a want-block is sent to a peer that
128126
// has an old version of Bitswap that doesn't support DONT_HAVE messages,
129127
// or when no response is received within a timeout.
128+
var sm *bssm.SessionManager
130129
onDontHaveTimeout := func(p peer.ID, dontHaves []cid.Cid) {
131-
// Simulate a DONT_HAVE message arriving to the WantManager
132-
wm.ReceiveFrom(ctx, p, nil, nil, dontHaves)
130+
// Simulate a message arriving with DONT_HAVEs
131+
sm.ReceiveFrom(ctx, p, nil, nil, dontHaves)
133132
}
134133
peerQueueFactory := func(ctx context.Context, p peer.ID) bspm.PeerQueue {
135134
return bsmq.New(ctx, p, network, onDontHaveTimeout)
@@ -138,25 +137,23 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
138137
sim := bssim.New()
139138
bpm := bsbpm.New()
140139
pm := bspm.New(ctx, peerQueueFactory, network.Self())
141-
wm = bswm.New(ctx, pm, sim, bpm)
142140
pqm := bspqm.New(ctx, network)
143141

144-
sessionFactory := func(ctx context.Context, id uint64, spm bssession.SessionPeerManager,
142+
sessionFactory := func(sessctx context.Context, id uint64, spm bssession.SessionPeerManager,
145143
sim *bssim.SessionInterestManager,
146144
pm bssession.PeerManager,
147145
bpm *bsbpm.BlockPresenceManager,
148146
notif notifications.PubSub,
149147
provSearchDelay time.Duration,
150148
rebroadcastDelay delay.D,
151149
self peer.ID) bssm.Session {
152-
return bssession.New(ctx, id, wm, spm, pqm, sim, pm, bpm, notif, provSearchDelay, rebroadcastDelay, self)
150+
return bssession.New(ctx, sessctx, id, spm, pqm, sim, pm, bpm, notif, provSearchDelay, rebroadcastDelay, self)
153151
}
154152
sessionPeerManagerFactory := func(ctx context.Context, id uint64) bssession.SessionPeerManager {
155153
return bsspm.New(id, network.ConnectionManager())
156154
}
157155
notif := notifications.New()
158-
sm := bssm.New(ctx, sessionFactory, sim, sessionPeerManagerFactory, bpm, pm, notif, network.Self())
159-
wm.SetSessionManager(sm)
156+
sm = bssm.New(ctx, sessionFactory, sim, sessionPeerManagerFactory, bpm, pm, notif, network.Self())
160157
engine := decision.NewEngine(ctx, bstore, network.ConnectionManager(), network.Self())
161158

162159
bs := &Bitswap{
@@ -166,7 +163,6 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
166163
process: px,
167164
newBlocks: make(chan cid.Cid, HasBlockBufferSize),
168165
provideKeys: make(chan cid.Cid, provideKeysBufferSize),
169-
wm: wm,
170166
pm: pm,
171167
pqm: pqm,
172168
sm: sm,
@@ -207,9 +203,6 @@ func New(parent context.Context, network bsnet.BitSwapNetwork,
207203

208204
// Bitswap instances implement the bitswap protocol.
209205
type Bitswap struct {
210-
// the wantlist tracks global wants for bitswap
211-
wm *bswm.WantManager
212-
213206
pm *bspm.PeerManager
214207

215208
// the provider query manager manages requests to find providers
@@ -357,7 +350,7 @@ func (bs *Bitswap) receiveBlocksFrom(ctx context.Context, from peer.ID, blks []b
357350

358351
// Send all block keys (including duplicates) to any sessions that want them.
359352
// (The duplicates are needed by sessions for accounting purposes)
360-
bs.wm.ReceiveFrom(ctx, from, allKs, haves, dontHaves)
353+
bs.sm.ReceiveFrom(ctx, from, allKs, haves, dontHaves)
361354

362355
// Send wanted blocks to decision engine
363356
bs.engine.ReceiveFrom(from, wanted, haves)
@@ -480,14 +473,14 @@ func (bs *Bitswap) blockstoreHas(blks []blocks.Block) []bool {
480473
// PeerConnected is called by the network interface
481474
// when a peer initiates a new connection to bitswap.
482475
func (bs *Bitswap) PeerConnected(p peer.ID) {
483-
bs.wm.Connected(p)
476+
bs.pm.Connected(p)
484477
bs.engine.PeerConnected(p)
485478
}
486479

487480
// PeerDisconnected is called by the network interface when a peer
488481
// closes a connection
489482
func (bs *Bitswap) PeerDisconnected(p peer.ID) {
490-
bs.wm.Disconnected(p)
483+
bs.pm.Disconnected(p)
491484
bs.engine.PeerDisconnected(p)
492485
}
493486

bitswap/docs/go-bitswap.png

-2.94 KB
Loading

bitswap/docs/go-bitswap.puml

+6-8
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,6 @@ node "Sending Blocks" {
1111
[Engine] --> [TaskWorker (workers.go)]
1212
}
1313

14-
node "Requesting Blocks" {
15-
[Bitswap] --* [WantManager]
16-
[WantManager] --> [BlockPresenceManager]
17-
[WantManager] --> [PeerManager]
18-
[PeerManager] --* [MessageQueue]
19-
}
20-
2114
node "Providing" {
2215
[Bitswap] --* [Provide Collector (workers.go)]
2316
[Provide Collector (workers.go)] --* [Provide Worker (workers.go)]
@@ -31,14 +24,19 @@ node "Sessions (smart requests)" {
3124
[Bitswap] --* [SessionManager]
3225
[SessionManager] --> [SessionInterestManager]
3326
[SessionManager] --o [Session]
27+
[SessionManager] --> [BlockPresenceManager]
3428
[Session] --* [sessionWantSender]
3529
[Session] --* [SessionPeerManager]
36-
[Session] --> [WantManager]
3730
[Session] --> [ProvideQueryManager]
3831
[Session] --* [sessionWants]
3932
[Session] --> [SessionInterestManager]
4033
[sessionWantSender] --> [BlockPresenceManager]
34+
}
35+
36+
node "Requesting Blocks" {
37+
[SessionManager] --> [PeerManager]
4138
[sessionWantSender] --> [PeerManager]
39+
[PeerManager] --* [MessageQueue]
4240
}
4341

4442
node "Network" {

bitswap/docs/how-bitswap-works.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ When a message is received, Bitswap
7474
So that the Engine can send responses to the wants
7575
- Informs the Engine of any received blocks
7676
So that the Engine can send the received blocks to any peers that want them
77-
- Informs the WantManager of received blocks, HAVEs and DONT_HAVEs
78-
So that the WantManager can inform interested sessions
77+
- Informs the SessionManager of received blocks, HAVEs and DONT_HAVEs
78+
So that the SessionManager can inform interested sessions
7979

8080
When the client makes an API call, Bitswap creates a new Session and calls the corresponding method (eg `GetBlocks()`).
8181

@@ -101,9 +101,10 @@ The PeerTaskQueue prioritizes tasks such that the peers with the least amount of
101101

102102
### Requesting Blocks
103103

104-
When the WantManager is informed of a new message, it
105-
- informs the SessionManager
106-
The SessionManager informs the Sessions that are interested in the received blocks and wants
104+
When the SessionManager is informed of a new message, it
105+
- informs the BlockPresenceManager
106+
The BlockPresenceManager keeps track of which peers have sent HAVES and DONT_HAVEs for each block
107+
- informs the Sessions that are interested in the received blocks and wants
107108
- informs the PeerManager of received blocks
108109
The PeerManager checks if any wants were send to a peer for the received blocks. If so it sends a `CANCEL` message to those peers.
109110

@@ -114,7 +115,7 @@ The Session starts in "discovery" mode. This means it doesn't have any peers yet
114115
When the client initially requests blocks from a Session, the Session
115116
- informs the SessionInterestManager that it is interested in the want
116117
- informs the sessionWantManager of the want
117-
- tells the WantManager to broadcast a `want-have` to all connected peers so as to discover which peers have the block
118+
- tells the PeerManager to broadcast a `want-have` to all connected peers so as to discover which peers have the block
118119
- queries the ProviderQueryManager to discover which peers have the block
119120

120121
When the session receives a message with `HAVE` or a `block`, it informs the SessionPeerManager. The SessionPeerManager keeps track of all peers in the session.

bitswap/internal/session/session.go

+42-26
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,6 @@ const (
2525
broadcastLiveWantsLimit = 64
2626
)
2727

28-
// WantManager is an interface that can be used to request blocks
29-
// from given peers.
30-
type WantManager interface {
31-
// BroadcastWantHaves sends want-haves to all connected peers (used for
32-
// session discovery)
33-
BroadcastWantHaves(context.Context, uint64, []cid.Cid)
34-
// RemoveSession removes the session from the WantManager (when the
35-
// session shuts down)
36-
RemoveSession(context.Context, uint64)
37-
}
38-
3928
// PeerManager keeps track of which sessions are interested in which peers
4029
// and takes care of sending wants for the sessions
4130
type PeerManager interface {
@@ -47,6 +36,11 @@ type PeerManager interface {
4736
UnregisterSession(uint64)
4837
// SendWants tells the PeerManager to send wants to the given peer
4938
SendWants(ctx context.Context, peerId peer.ID, wantBlocks []cid.Cid, wantHaves []cid.Cid)
39+
// BroadcastWantHaves sends want-haves to all connected peers (used for
40+
// session discovery)
41+
BroadcastWantHaves(context.Context, []cid.Cid)
42+
// SendCancels tells the PeerManager to send cancels to all peers
43+
SendCancels(context.Context, []cid.Cid)
5044
}
5145

5246
// SessionPeerManager keeps track of peers in the session
@@ -97,8 +91,10 @@ type op struct {
9791
// info to, and who to request blocks from.
9892
type Session struct {
9993
// dependencies
100-
ctx context.Context
101-
wm WantManager
94+
bsctx context.Context // context for bitswap
95+
ctx context.Context // context for session
96+
pm PeerManager
97+
bpm *bsbpm.BlockPresenceManager
10298
sprm SessionPeerManager
10399
providerFinder ProviderFinder
104100
sim *bssim.SessionInterestManager
@@ -129,9 +125,10 @@ type Session struct {
129125

130126
// New creates a new bitswap session whose lifetime is bounded by the
131127
// given context.
132-
func New(ctx context.Context,
128+
func New(
129+
bsctx context.Context, // context for bitswap
130+
ctx context.Context, // context for this session
133131
id uint64,
134-
wm WantManager,
135132
sprm SessionPeerManager,
136133
providerFinder ProviderFinder,
137134
sim *bssim.SessionInterestManager,
@@ -144,8 +141,10 @@ func New(ctx context.Context,
144141
s := &Session{
145142
sw: newSessionWants(broadcastLiveWantsLimit),
146143
tickDelayReqs: make(chan time.Duration),
144+
bsctx: bsctx,
147145
ctx: ctx,
148-
wm: wm,
146+
pm: pm,
147+
bpm: bpm,
149148
sprm: sprm,
150149
providerFinder: providerFinder,
151150
sim: sim,
@@ -301,13 +300,13 @@ func (s *Session) run(ctx context.Context) {
301300
s.sw.WantsSent(oper.keys)
302301
case opBroadcast:
303302
// Broadcast want-haves to all peers
304-
s.broadcastWantHaves(ctx, oper.keys)
303+
s.broadcast(ctx, oper.keys)
305304
default:
306305
panic("unhandled operation")
307306
}
308307
case <-s.idleTick.C:
309308
// The session hasn't received blocks for a while, broadcast
310-
s.broadcastWantHaves(ctx, nil)
309+
s.broadcast(ctx, nil)
311310
case <-s.periodicSearchTimer.C:
312311
// Periodically search for a random live want
313312
s.handlePeriodicSearch(ctx)
@@ -325,23 +324,23 @@ func (s *Session) run(ctx context.Context) {
325324
// Called when the session hasn't received any blocks for some time, or when
326325
// all peers in the session have sent DONT_HAVE for a particular set of CIDs.
327326
// Send want-haves to all connected peers, and search for new peers with the CID.
328-
func (s *Session) broadcastWantHaves(ctx context.Context, wants []cid.Cid) {
327+
func (s *Session) broadcast(ctx context.Context, wants []cid.Cid) {
329328
// If this broadcast is because of an idle timeout (we haven't received
330329
// any blocks for a while) then broadcast all pending wants
331330
if wants == nil {
332331
wants = s.sw.PrepareBroadcast()
333332
}
334333

335334
// Broadcast a want-have for the live wants to everyone we're connected to
336-
s.wm.BroadcastWantHaves(ctx, s.id, wants)
335+
s.broadcastWantHaves(ctx, wants)
337336

338337
// do not find providers on consecutive ticks
339338
// -- just rely on periodic search widening
340339
if len(wants) > 0 && (s.consecutiveTicks == 0) {
341340
// Search for providers who have the first want in the list.
342341
// Typically if the provider has the first block they will have
343342
// the rest of the blocks also.
344-
log.Debugf("Ses%d: FindMorePeers with want %s (1st of %d wants)", s.id, wants[0], len(wants))
343+
log.Debugw("FindMorePeers", "session", s.id, "cid", wants[0], "pending", len(wants))
345344
s.findMorePeers(ctx, wants[0])
346345
}
347346
s.resetIdleTick()
@@ -364,7 +363,7 @@ func (s *Session) handlePeriodicSearch(ctx context.Context) {
364363
// for new providers for blocks.
365364
s.findMorePeers(ctx, randomWant)
366365

367-
s.wm.BroadcastWantHaves(ctx, s.id, []cid.Cid{randomWant})
366+
s.broadcastWantHaves(ctx, []cid.Cid{randomWant})
368367

369368
s.periodicSearchTimer.Reset(s.periodicSearchDelay.NextWaitTime())
370369
}
@@ -390,8 +389,19 @@ func (s *Session) handleShutdown() {
390389
// Shut down the sessionWantSender (blocks until sessionWantSender stops
391390
// sending)
392391
s.sws.Shutdown()
393-
// Remove the session from the want manager
394-
s.wm.RemoveSession(s.ctx, s.id)
392+
393+
// Remove session's interest in the given blocks.
394+
cancelKs := s.sim.RemoveSessionInterest(s.id)
395+
396+
// Free up block presence tracking for keys that no session is interested
397+
// in anymore
398+
s.bpm.RemoveKeys(cancelKs)
399+
400+
// Send CANCEL to all peers for blocks that no session is interested in
401+
// anymore.
402+
// Note: use bitswap context because session context has already been
403+
// cancelled.
404+
s.pm.SendCancels(s.bsctx, cancelKs)
395405
}
396406

397407
// handleReceive is called when the session receives blocks from a peer
@@ -439,11 +449,17 @@ func (s *Session) wantBlocks(ctx context.Context, newks []cid.Cid) {
439449
// No peers discovered yet, broadcast some want-haves
440450
ks := s.sw.GetNextWants()
441451
if len(ks) > 0 {
442-
log.Infof("Ses%d: No peers - broadcasting %d want HAVE requests\n", s.id, len(ks))
443-
s.wm.BroadcastWantHaves(ctx, s.id, ks)
452+
log.Infow("No peers - broadcasting", "session", s.id, "want-count", len(ks))
453+
s.broadcastWantHaves(ctx, ks)
444454
}
445455
}
446456

457+
// Send want-haves to all connected peers
458+
func (s *Session) broadcastWantHaves(ctx context.Context, wants []cid.Cid) {
459+
log.Debugw("broadcastWantHaves", "session", s.id, "cids", wants)
460+
s.pm.BroadcastWantHaves(ctx, wants)
461+
}
462+
447463
// The session will broadcast if it has outstanding wants and doesn't receive
448464
// any blocks for some time.
449465
// The length of time is calculated

0 commit comments

Comments
 (0)