wantmanager.go 3.51 KB
Newer Older
1 2 3 4 5
package wantmanager

import (
	"context"

6 7 8
	bsbpm "github.com/ipfs/go-bitswap/internal/blockpresencemanager"
	bssim "github.com/ipfs/go-bitswap/internal/sessioninterestmanager"
	"github.com/ipfs/go-bitswap/internal/sessionmanager"
Dirk McCormick's avatar
Dirk McCormick committed
9
	logging "github.com/ipfs/go-log"
10 11

	cid "github.com/ipfs/go-cid"
Raúl Kripalani's avatar
Raúl Kripalani committed
12
	peer "github.com/libp2p/go-libp2p-core/peer"
13 14
)

Dirk McCormick's avatar
Dirk McCormick committed
15 16
var log = logging.Logger("bitswap")

dirkmc's avatar
dirkmc committed
17
// PeerHandler sends wants / cancels to other peers
18
type PeerHandler interface {
19 20
	// Connected is called when a peer connects.
	Connected(p peer.ID)
dirkmc's avatar
dirkmc committed
21
	// Disconnected is called when a peer disconnects
22
	Disconnected(p peer.ID)
dirkmc's avatar
dirkmc committed
23 24 25 26 27
	// BroadcastWantHaves sends want-haves to all connected peers
	BroadcastWantHaves(ctx context.Context, wantHaves []cid.Cid)
	// SendCancels sends cancels to all peers that had previously been sent
	// a want-block or want-have for the given key
	SendCancels(context.Context, []cid.Cid)
28 29
}

dirkmc's avatar
dirkmc committed
30 31 32
// SessionManager receives incoming messages and distributes them to sessions
type SessionManager interface {
	ReceiveFrom(p peer.ID, blks []cid.Cid, haves []cid.Cid, dontHaves []cid.Cid) []sessionmanager.Session
33 34
}

dirkmc's avatar
dirkmc committed
35 36 37 38
// WantManager
// - informs the SessionManager and BlockPresenceManager of incoming information
//   and cancelled sessions
// - informs the PeerManager of connects and disconnects
39
type WantManager struct {
dirkmc's avatar
dirkmc committed
40 41 42 43
	peerHandler PeerHandler
	sim         *bssim.SessionInterestManager
	bpm         *bsbpm.BlockPresenceManager
	sm          SessionManager
44 45
}

46
// New initializes a new WantManager for a given context.
dirkmc's avatar
dirkmc committed
47
func New(ctx context.Context, peerHandler PeerHandler, sim *bssim.SessionInterestManager, bpm *bsbpm.BlockPresenceManager) *WantManager {
48
	return &WantManager{
dirkmc's avatar
dirkmc committed
49 50 51
		peerHandler: peerHandler,
		sim:         sim,
		bpm:         bpm,
52 53 54
	}
}

dirkmc's avatar
dirkmc committed
55 56
func (wm *WantManager) SetSessionManager(sm SessionManager) {
	wm.sm = sm
57 58
}

dirkmc's avatar
dirkmc committed
59 60 61 62 63 64 65 66
// ReceiveFrom is called when a new message is received
func (wm *WantManager) ReceiveFrom(ctx context.Context, p peer.ID, blks []cid.Cid, haves []cid.Cid, dontHaves []cid.Cid) {
	// Record block presence for HAVE / DONT_HAVE
	wm.bpm.ReceiveFrom(p, haves, dontHaves)
	// Inform interested sessions
	wm.sm.ReceiveFrom(p, blks, haves, dontHaves)
	// Send CANCEL to all peers with want-have / want-block
	wm.peerHandler.SendCancels(ctx, blks)
67 68
}

dirkmc's avatar
dirkmc committed
69 70 71
// BroadcastWantHaves is called when want-haves should be broadcast to all
// connected peers (as part of session discovery)
func (wm *WantManager) BroadcastWantHaves(ctx context.Context, ses uint64, wantHaves []cid.Cid) {
72 73
	// TODO: Avoid calling broadcast through here. It doesn't fit with
	// everything else this module does.
74

75
	log.Debugf("BroadcastWantHaves session%d: %s", ses, wantHaves)
dirkmc's avatar
dirkmc committed
76 77
	// Send want-haves to all peers
	wm.peerHandler.BroadcastWantHaves(ctx, wantHaves)
78 79
}

dirkmc's avatar
dirkmc committed
80 81
// RemoveSession is called when the session is shut down
func (wm *WantManager) RemoveSession(ctx context.Context, ses uint64) {
82
	// Remove session's interest in the given blocks.
dirkmc's avatar
dirkmc committed
83
	cancelKs := wm.sim.RemoveSessionInterest(ses)
84

dirkmc's avatar
dirkmc committed
85 86 87
	// Free up block presence tracking for keys that no session is interested
	// in anymore
	wm.bpm.RemoveKeys(cancelKs)
88

dirkmc's avatar
dirkmc committed
89 90
	// Send CANCEL to all peers for blocks that no session is interested in anymore
	wm.peerHandler.SendCancels(ctx, cancelKs)
91 92
}

dirkmc's avatar
dirkmc committed
93 94 95 96
// Connected is called when a new peer connects
func (wm *WantManager) Connected(p peer.ID) {
	// Tell the peer handler that there is a new connection and give it the
	// list of outstanding broadcast wants
97
	wm.peerHandler.Connected(p)
98 99
}

dirkmc's avatar
dirkmc committed
100 101 102
// Disconnected is called when a peer disconnects
func (wm *WantManager) Disconnected(p peer.ID) {
	wm.peerHandler.Disconnected(p)
103
}