implement peermanager to control outgoing messages
Also more refactoring of bitswap in general, including some perf improvements and eventlog removal. clean up, and buffer channels move some things around correctly buffer work messages more cleanup, and improve test perf remove unneccessary test revert changes to bitswap message, they werent necessary
Jeromy committed
May 8, 2015 at 23:55 UTC
a159e6825c2c8c82b734e290e8fc2116d3afd429
12 files changed
+275
-120
exchange/bitswap/bitswap.go
+18
-70
@@ -91,7 +91,9 @@ func New(parent context.Context, p peer.ID, network bsnet.BitSwapNetwork,
91
process: px,
92
newBlocks: make(chan *blocks.Block, HasBlockBufferSize),
93
provideKeys: make(chan u.Key),
94
+ pm: NewPeerManager(network),
95
}
96
+ go bs.pm.Run(ctx)
97
network.SetDelegate(bs)
98
99
// Start up bitswaps async worker routines
@@ -108,6 +110,10 @@ type Bitswap struct {
110
// network delivers messages on behalf of the session
111
network bsnet.BitSwapNetwork
112
113
+ // the peermanager manages sending messages to peers in a way that
114
+ // wont block bitswap operation
115
+ pm *PeerManager
116
+
117
// blockstore is the local database
118
// NB: ensure threadsafety
119
blockstore blockstore.Blockstore
@@ -217,7 +223,6 @@ func (bs *Bitswap) GetBlocks(ctx context.Context, keys []u.Key) (<-chan *blocks.
223
// HasBlock announces the existance of a block to this bitswap service. The
224
// service will potentially notify its peers.
225
func (bs *Bitswap) HasBlock(ctx context.Context, blk *blocks.Block) error {
220
- log.Event(ctx, "hasBlock", blk)
226
select {
227
case <-bs.process.Closing():
228
return errors.New("bitswap is closed")
@@ -227,6 +232,7 @@ func (bs *Bitswap) HasBlock(ctx context.Context, blk *blocks.Block) error {
232
if err := bs.blockstore.Put(blk); err != nil {
233
return err
234
}
235
+
236
bs.wantlist.Remove(blk.Key())
237
bs.notifications.Publish(blk)
238
select {
@@ -239,7 +245,6 @@ func (bs *Bitswap) HasBlock(ctx context.Context, blk *blocks.Block) error {
245
246
func (bs *Bitswap) sendWantlistMsgToPeers(ctx context.Context, m bsmsg.BitSwapMessage, peers <-chan peer.ID) error {
247
set := pset.New()
242
- wg := sync.WaitGroup{}
248
249
loop:
250
for {
@@ -253,37 +258,22 @@ loop:
258
continue
259
}
260
256
- wg.Add(1)
257
- go func(p peer.ID) {
258
- defer wg.Done()
259
- if err := bs.send(ctx, p, m); err != nil {
260
- log.Debug(err) // TODO remove if too verbose
261
- }
262
- }(peerToQuery)
261
+ bs.pm.Send(peerToQuery, m)
262
case <-ctx.Done():
263
return nil
264
}
265
}
267
- done := make(chan struct{})
268
- go func() {
269
- wg.Wait()
270
- close(done)
271
- }()
272
-
273
- select {
274
- case <-done:
275
- case <-ctx.Done():
276
- // NB: we may be abandoning goroutines here before they complete
277
- // this shouldnt be an issue because they will complete soon anyways
278
- // we just don't want their being slow to impact bitswap transfer speeds
279
- }
266
return nil
267
}
268
269
func (bs *Bitswap) sendWantlistToPeers(ctx context.Context, peers <-chan peer.ID) error {
270
+ entries := bs.wantlist.Entries()
271
+ if len(entries) == 0 {
272
+ return nil
273
+ }
274
message := bsmsg.New()
275
message.SetFull(true)
286
- for _, wanted := range bs.wantlist.Entries() {
276
+ for _, wanted := range entries {
277
message.AddEntry(wanted.Key, wanted.Priority)
278
}
279
return bs.sendWantlistMsgToPeers(ctx, message, peers)
@@ -326,7 +316,7 @@ func (bs *Bitswap) sendWantlistToProviders(ctx context.Context, entries []wantli
316
317
// TODO(brian): handle errors
318
func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg.BitSwapMessage) error {
329
- defer log.EventBegin(ctx, "receiveMessage", p, incoming).Done()
319
+ //defer log.EventBegin(ctx, "receiveMessage", p, incoming).Done()
320
321
// This call records changes to wantlists, blocks received,
322
// and number of bytes transfered.
@@ -356,6 +346,7 @@ func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg
346
// Connected/Disconnected warns bitswap about peer connections
347
func (bs *Bitswap) PeerConnected(p peer.ID) {
348
// TODO: add to clientWorker??
349
+ bs.pm.Connected(p)
350
peers := make(chan peer.ID, 1)
351
peers <- p
352
close(peers)
@@ -367,6 +358,7 @@ func (bs *Bitswap) PeerConnected(p peer.ID) {
358
359
// Connected/Disconnected warns bitswap about peer connections
360
func (bs *Bitswap) PeerDisconnected(p peer.ID) {
361
+ bs.pm.Disconnected(p)
362
bs.engine.PeerDisconnected(p)
363
}
364
@@ -381,19 +373,7 @@ func (bs *Bitswap) cancelBlocks(ctx context.Context, bkeys []u.Key) {
373
message.Cancel(k)
374
}
375
384
- wg := sync.WaitGroup{}
385
- for _, p := range bs.engine.Peers() {
386
- wg.Add(1)
387
- go func(p peer.ID) {
388
- defer wg.Done()
389
- err := bs.send(ctx, p, message)
390
- if err != nil {
391
- log.Warningf("Error sending message: %s", err)
392
- return
393
- }
394
- }(p)
395
- }
396
- wg.Wait()
376
+ bs.pm.Broadcast(message)
377
return
378
}
379
@@ -408,29 +388,7 @@ func (bs *Bitswap) wantNewBlocks(ctx context.Context, bkeys []u.Key) {
388
message.AddEntry(k, kMaxPriority-i)
389
}
390
411
- wg := sync.WaitGroup{}
412
- for _, p := range bs.engine.Peers() {
413
- wg.Add(1)
414
- go func(p peer.ID) {
415
- defer wg.Done()
416
- err := bs.send(ctx, p, message)
417
- if err != nil {
418
- log.Debugf("Error sending message: %s", err)
419
- }
420
- }(p)
421
- }
422
- done := make(chan struct{})
423
- go func() {
424
- wg.Wait()
425
- close(done)
426
- }()
427
- select {
428
- case <-done:
429
- case <-ctx.Done():
430
- // NB: we may be abandoning goroutines here before they complete
431
- // this shouldnt be an issue because they will complete soon anyways
432
- // we just don't want their being slow to impact bitswap transfer speeds
433
- }
391
+ bs.pm.Broadcast(message)
392
}
393
394
func (bs *Bitswap) ReceiveError(err error) {
@@ -439,16 +397,6 @@ func (bs *Bitswap) ReceiveError(err error) {
397
// TODO bubble the network error up to the parent context/error logger
398
}
399
442
-// send strives to ensure that accounting is always performed when a message is
443
-// sent
444
-func (bs *Bitswap) send(ctx context.Context, p peer.ID, m bsmsg.BitSwapMessage) error {
445
- defer log.EventBegin(ctx, "sendMessage", p, m).Done()
446
- if err := bs.network.SendMessage(ctx, p, m); err != nil {
447
- return err
448
- }
449
- return bs.engine.MessageSent(p, m)
450
-}
451
-
400
func (bs *Bitswap) Close() error {
401
return bs.process.Close()
402
}
exchange/bitswap/bitswap_test.go
+6
-29
@@ -13,7 +13,6 @@ import (
13
blocks "github.com/ipfs/go-ipfs/blocks"
14
blocksutil "github.com/ipfs/go-ipfs/blocks/blocksutil"
15
tn "github.com/ipfs/go-ipfs/exchange/bitswap/testnet"
16
- p2ptestutil "github.com/ipfs/go-ipfs/p2p/test/util"
16
mockrouting "github.com/ipfs/go-ipfs/routing/mock"
17
delay "github.com/ipfs/go-ipfs/thirdparty/delay"
18
u "github.com/ipfs/go-ipfs/util"
@@ -36,30 +35,6 @@ func TestClose(t *testing.T) {
35
bitswap.Exchange.GetBlock(context.Background(), block.Key())
36
}
37
39
-func TestProviderForKeyButNetworkCannotFind(t *testing.T) { // TODO revisit this
40
-
41
- rs := mockrouting.NewServer()
42
- net := tn.VirtualNetwork(rs, delay.Fixed(kNetworkDelay))
43
- g := NewTestSessionGenerator(net)
44
- defer g.Close()
45
-
46
- block := blocks.NewBlock([]byte("block"))
47
- pinfo := p2ptestutil.RandTestBogusIdentityOrFatal(t)
48
- rs.Client(pinfo).Provide(context.Background(), block.Key()) // but not on network
49
-
50
- solo := g.Next()
51
- defer solo.Exchange.Close()
52
-
53
- ctx, _ := context.WithTimeout(context.Background(), time.Nanosecond)
54
- _, err := solo.Exchange.GetBlock(ctx, block.Key())
55
-
56
- if err != context.DeadlineExceeded {
57
- t.Fatal("Expected DeadlineExceeded error")
58
- }
59
-}
60
-
61
-// TestGetBlockAfterRequesting...
62
-
38
func TestGetBlockFromPeerAfterPeerAnnounces(t *testing.T) {
39
40
net := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
@@ -67,14 +42,15 @@ func TestGetBlockFromPeerAfterPeerAnnounces(t *testing.T) {
42
g := NewTestSessionGenerator(net)
43
defer g.Close()
44
70
- hasBlock := g.Next()
45
+ peers := g.Instances(2)
46
+ hasBlock := peers[0]
47
defer hasBlock.Exchange.Close()
48
49
if err := hasBlock.Exchange.HasBlock(context.Background(), block); err != nil {
50
t.Fatal(err)
51
}
52
77
- wantsBlock := g.Next()
53
+ wantsBlock := peers[1]
54
defer wantsBlock.Exchange.Close()
55
56
ctx, _ := context.WithTimeout(context.Background(), time.Second)
@@ -196,8 +172,9 @@ func TestSendToWantingPeer(t *testing.T) {
172
prev := rebroadcastDelay.Set(time.Second / 2)
173
defer func() { rebroadcastDelay.Set(prev) }()
174
199
- peerA := sg.Next()
200
- peerB := sg.Next()
175
+ peers := sg.Instances(2)
176
+ peerA := peers[0]
177
+ peerB := peers[1]
178
179
t.Logf("Session %v\n", peerA.Peer)
180
t.Logf("Session %v\n", peerB.Peer)
exchange/bitswap/decision/engine.go
+11
-11
@@ -5,6 +5,7 @@ import (
5
"sync"
6
7
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
8
+ blocks "github.com/ipfs/go-ipfs/blocks"
9
bstore "github.com/ipfs/go-ipfs/blocks/blockstore"
10
bsmsg "github.com/ipfs/go-ipfs/exchange/bitswap/message"
11
wl "github.com/ipfs/go-ipfs/exchange/bitswap/wantlist"
@@ -53,8 +54,9 @@ const (
54
type Envelope struct {
55
// Peer is the intended recipient
56
Peer peer.ID
56
- // Message is the payload
57
- Message bsmsg.BitSwapMessage
57
+
58
+ // Block is the payload
59
+ Block *blocks.Block
60
61
// A callback to notify the decision queue that the task is complete
62
Sent func()
@@ -151,12 +153,10 @@ func (e *Engine) nextEnvelope(ctx context.Context) (*Envelope, error) {
153
continue
154
}
155
154
- m := bsmsg.New() // TODO: maybe add keys from our wantlist?
155
- m.AddBlock(block)
156
return &Envelope{
157
- Peer: nextTask.Target,
158
- Message: m,
159
- Sent: nextTask.Done,
157
+ Peer: nextTask.Target,
158
+ Block: block,
159
+ Sent: nextTask.Done,
160
}, nil
161
}
162
}
@@ -185,7 +185,7 @@ func (e *Engine) MessageReceived(p peer.ID, m bsmsg.BitSwapMessage) error {
185
defer e.lock.Unlock()
186
187
if len(m.Wantlist()) == 0 && len(m.Blocks()) == 0 {
188
- log.Debug("received empty message from", p)
188
+ log.Debugf("received empty message from %s", p)
189
}
190
191
newWorkExists := false
@@ -202,11 +202,11 @@ func (e *Engine) MessageReceived(p peer.ID, m bsmsg.BitSwapMessage) error {
202
203
for _, entry := range m.Wantlist() {
204
if entry.Cancel {
205
- log.Debug("cancel", entry.Key)
205
+ log.Debugf("cancel %s", entry.Key)
206
l.CancelWant(entry.Key)
207
e.peerRequestQueue.Remove(entry.Key, p)
208
} else {
209
- log.Debug("wants", entry.Key, entry.Priority)
209
+ log.Debugf("wants %s", entry.Key, entry.Priority)
210
l.Wants(entry.Key, entry.Priority)
211
if exists, err := e.bs.Has(entry.Key); err == nil && exists {
212
e.peerRequestQueue.Push(entry.Entry, p)
@@ -216,7 +216,7 @@ func (e *Engine) MessageReceived(p peer.ID, m bsmsg.BitSwapMessage) error {
216
}
217
218
for _, block := range m.Blocks() {
219
- log.Debug("got block %s %d bytes", block.Key(), len(block.Data))
219
+ log.Debugf("got block %s %d bytes", block.Key(), len(block.Data))
220
l.ReceivedBytes(len(block.Data))
221
for _, l := range e.ledgerMap {
222
if entry, ok := l.WantListContains(block.Key()); ok {
exchange/bitswap/decision/engine_test.go
+1
-1
@@ -185,7 +185,7 @@ func checkHandledInOrder(t *testing.T, e *Engine, keys []string) error {
185
for _, k := range keys {
186
next := <-e.Outbox()
187
envelope := <-next
188
- received := envelope.Message.Blocks()[0]
188
+ received := envelope.Block
189
expected := blocks.NewBlock([]byte(k))
190
if received.Key() != expected.Key() {
191
return errors.New(fmt.Sprintln("received", string(received.Data), "expected", string(expected.Data)))
exchange/bitswap/decision/peer_request_queue.go
+1
-1
@@ -156,7 +156,7 @@ func (t *peerRequestTask) SetIndex(i int) {
156
157
// taskKey returns a key that uniquely identifies a task.
158
func taskKey(p peer.ID, k u.Key) string {
159
- return string(p.String() + k.String())
159
+ return string(p) + string(k)
160
}
161
162
// FIFO is a basic task comparator that returns tasks in the order created.
exchange/bitswap/message/message.go
+9
-2
@@ -29,6 +29,8 @@ type BitSwapMessage interface {
29
30
Cancel(key u.Key)
31
32
+ Empty() bool
33
+
34
// Sets whether or not the contained wantlist represents the entire wantlist
35
// true = full wantlist
36
// false = wantlist 'patch'
@@ -51,7 +53,7 @@ type Exportable interface {
53
type impl struct {
54
full bool
55
wantlist map[u.Key]Entry
54
- blocks map[u.Key]*blocks.Block // map to detect duplicates
56
+ blocks map[u.Key]*blocks.Block
57
}
58
59
func New() BitSwapMessage {
@@ -92,6 +94,10 @@ func (m *impl) Full() bool {
94
return m.full
95
}
96
97
+func (m *impl) Empty() bool {
98
+ return len(m.blocks) == 0 && len(m.wantlist) == 0
99
+}
100
+
101
func (m *impl) Wantlist() []Entry {
102
var out []Entry
103
for _, e := range m.wantlist {
@@ -101,7 +107,7 @@ func (m *impl) Wantlist() []Entry {
107
}
108
109
func (m *impl) Blocks() []*blocks.Block {
104
- bs := make([]*blocks.Block, 0)
110
+ bs := make([]*blocks.Block, 0, len(m.blocks))
111
for _, block := range m.blocks {
112
bs = append(bs, block)
113
}
@@ -109,6 +115,7 @@ func (m *impl) Blocks() []*blocks.Block {
115
}
116
117
func (m *impl) Cancel(k u.Key) {
118
+ delete(m.wantlist, k)
119
m.addEntry(k, 0, true)
120
}
121
exchange/bitswap/network/interface.go
+2
@@ -23,6 +23,8 @@ type BitSwapNetwork interface {
23
// network.
24
SetDelegate(Receiver)
25
26
+ ConnectTo(context.Context, peer.ID) error
27
+
28
Routing
29
}
30
exchange/bitswap/network/ipfs_impl.go
+4
@@ -97,6 +97,10 @@ func (bsnet *impl) SetDelegate(r Receiver) {
97
bsnet.receiver = r
98
}
99
100
+func (bsnet *impl) ConnectTo(ctx context.Context, p peer.ID) error {
101
+ return bsnet.host.Connect(ctx, peer.PeerInfo{ID: p})
102
+}
103
+
104
// FindProvidersAsync returns a channel of providers for the given key
105
func (bsnet *impl) FindProvidersAsync(ctx context.Context, k util.Key, max int) <-chan peer.ID {
106
exchange/bitswap/peermanager.go
new
+203
@@ -0,0 +1,203 @@
1
+package bitswap
2
+
3
+import (
4
+ "sync"
5
+
6
+ context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
7
+ engine "github.com/ipfs/go-ipfs/exchange/bitswap/decision"
8
+ bsmsg "github.com/ipfs/go-ipfs/exchange/bitswap/message"
9
+ bsnet "github.com/ipfs/go-ipfs/exchange/bitswap/network"
10
+ peer "github.com/ipfs/go-ipfs/p2p/peer"
11
+ u "github.com/ipfs/go-ipfs/util"
12
+)
13
+
14
+type PeerManager struct {
15
+ receiver bsnet.Receiver
16
+
17
+ incoming chan *msgPair
18
+ connect chan peer.ID
19
+ disconnect chan peer.ID
20
+
21
+ peers map[peer.ID]*msgQueue
22
+
23
+ network bsnet.BitSwapNetwork
24
+}
25
+
26
+func NewPeerManager(network bsnet.BitSwapNetwork) *PeerManager {
27
+ return &PeerManager{
28
+ incoming: make(chan *msgPair, 10),
29
+ connect: make(chan peer.ID, 10),
30
+ disconnect: make(chan peer.ID, 10),
31
+ peers: make(map[peer.ID]*msgQueue),
32
+ network: network,
33
+ }
34
+}
35
+
36
+type msgPair struct {
37
+ to peer.ID
38
+ msg bsmsg.BitSwapMessage
39
+}
40
+
41
+type cancellation struct {
42
+ who peer.ID
43
+ blk u.Key
44
+}
45
+
46
+type msgQueue struct {
47
+ p peer.ID
48
+
49
+ lk sync.Mutex
50
+ wlmsg bsmsg.BitSwapMessage
51
+
52
+ work chan struct{}
53
+ done chan struct{}
54
+}
55
+
56
+func (pm *PeerManager) SendBlock(env *engine.Envelope) {
57
+ // Blocks need to be sent synchronously to maintain proper backpressure
58
+ // throughout the network stack
59
+ defer env.Sent()
60
+
61
+ msg := bsmsg.New()
62
+ msg.AddBlock(env.Block)
63
+ err := pm.network.SendMessage(context.TODO(), env.Peer, msg)
64
+ if err != nil {
65
+ log.Error(err)
66
+ }
67
+}
68
+
69
+func (pm *PeerManager) startPeerHandler(p peer.ID) {
70
+ _, ok := pm.peers[p]
71
+ if ok {
72
+ // TODO: log an error?
73
+ return
74
+ }
75
+
76
+ mq := new(msgQueue)
77
+ mq.done = make(chan struct{})
78
+ mq.work = make(chan struct{}, 1)
79
+ mq.p = p
80
+
81
+ pm.peers[p] = mq
82
+ go pm.runQueue(mq)
83
+}
84
+
85
+func (pm *PeerManager) stopPeerHandler(p peer.ID) {
86
+ pq, ok := pm.peers[p]
87
+ if !ok {
88
+ // TODO: log error?
89
+ return
90
+ }
91
+
92
+ close(pq.done)
93
+ delete(pm.peers, p)
94
+}
95
+
96
+func (pm *PeerManager) runQueue(mq *msgQueue) {
97
+ for {
98
+ select {
99
+ case <-mq.work: // there is work to be done
100
+
101
+ // TODO: this might not need to be done every time, figure out
102
+ // a good heuristic
103
+ err := pm.network.ConnectTo(context.TODO(), mq.p)
104
+ if err != nil {
105
+ log.Error(err)
106
+ // TODO: cant connect, what now?
107
+ }
108
+
109
+ // grab messages from queue
110
+ mq.lk.Lock()
111
+ wlm := mq.wlmsg
112
+ mq.wlmsg = nil
113
+ mq.lk.Unlock()
114
+
115
+ if wlm != nil && !wlm.Empty() {
116
+ // send wantlist updates
117
+ err = pm.network.SendMessage(context.TODO(), mq.p, wlm)
118
+ if err != nil {
119
+ log.Error("bitswap send error: ", err)
120
+ // TODO: what do we do if this fails?
121
+ }
122
+ }
123
+ case <-mq.done:
124
+ return
125
+ }
126
+ }
127
+}
128
+
129
+func (pm *PeerManager) Send(to peer.ID, msg bsmsg.BitSwapMessage) {
130
+ if len(msg.Blocks()) > 0 {
131
+ panic("no blocks here!")
132
+ }
133
+ pm.incoming <- &msgPair{to: to, msg: msg}
134
+}
135
+
136
+func (pm *PeerManager) Broadcast(msg bsmsg.BitSwapMessage) {
137
+ pm.incoming <- &msgPair{msg: msg}
138
+}
139
+
140
+func (pm *PeerManager) Connected(p peer.ID) {
141
+ pm.connect <- p
142
+}
143
+
144
+func (pm *PeerManager) Disconnected(p peer.ID) {
145
+ pm.disconnect <- p
146
+}
147
+
148
+// TODO: use goprocess here once i trust it
149
+func (pm *PeerManager) Run(ctx context.Context) {
150
+ for {
151
+ select {
152
+ case msgp := <-pm.incoming:
153
+
154
+ // Broadcast message to all if recipient not set
155
+ if msgp.to == "" {
156
+ for _, p := range pm.peers {
157
+ p.addMessage(msgp.msg)
158
+ }
159
+ continue
160
+ }
161
+
162
+ p, ok := pm.peers[msgp.to]
163
+ if !ok {
164
+ //TODO: decide, drop message? or dial?
165
+ pm.startPeerHandler(msgp.to)
166
+ p = pm.peers[msgp.to]
167
+ }
168
+
169
+ p.addMessage(msgp.msg)
170
+ case p := <-pm.connect:
171
+ pm.startPeerHandler(p)
172
+ case p := <-pm.disconnect:
173
+ pm.stopPeerHandler(p)
174
+ case <-ctx.Done():
175
+ return
176
+ }
177
+ }
178
+}
179
+
180
+func (mq *msgQueue) addMessage(msg bsmsg.BitSwapMessage) {
181
+ mq.lk.Lock()
182
+ defer func() {
183
+ mq.lk.Unlock()
184
+ select {
185
+ case mq.work <- struct{}{}:
186
+ default:
187
+ }
188
+ }()
189
+
190
+ if mq.wlmsg == nil || msg.Full() {
191
+ mq.wlmsg = msg
192
+ return
193
+ }
194
+
195
+ // TODO: add a msg.Combine(...) method
196
+ for _, e := range msg.Wantlist() {
197
+ if e.Cancel {
198
+ mq.wlmsg.Cancel(e.Key)
199
+ } else {
200
+ mq.wlmsg.AddEntry(e.Key, e.Priority)
201
+ }
202
+ }
203
+}
exchange/bitswap/testnet/virtual.go
+9
@@ -119,3 +119,12 @@ func (nc *networkClient) Provide(ctx context.Context, k util.Key) error {
119
func (nc *networkClient) SetDelegate(r bsnet.Receiver) {
120
nc.Receiver = r
121
}
122
+
123
+func (nc *networkClient) ConnectTo(_ context.Context, p peer.ID) error {
124
+ if !nc.network.HasPeer(p) {
125
+ return errors.New("no such peer in network")
126
+ }
127
+ nc.network.clients[p].PeerConnected(nc.local)
128
+ nc.Receiver.PeerConnected(p)
129
+ return nil
130
+}
exchange/bitswap/testutils.go
+8
-3
@@ -7,7 +7,6 @@ import (
7
ds_sync "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
8
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
blockstore "github.com/ipfs/go-ipfs/blocks/blockstore"
10
- exchange "github.com/ipfs/go-ipfs/exchange"
10
tn "github.com/ipfs/go-ipfs/exchange/bitswap/testnet"
11
peer "github.com/ipfs/go-ipfs/p2p/peer"
12
p2ptestutil "github.com/ipfs/go-ipfs/p2p/test/util"
@@ -56,12 +55,18 @@ func (g *SessionGenerator) Instances(n int) []Instance {
55
inst := g.Next()
56
instances = append(instances, inst)
57
}
58
+ for i, inst := range instances {
59
+ for j := i + 1; j < len(instances); j++ {
60
+ oinst := instances[j]
61
+ inst.Exchange.PeerConnected(oinst.Peer)
62
+ }
63
+ }
64
return instances
65
}
66
67
type Instance struct {
68
Peer peer.ID
64
- Exchange exchange.Interface
69
+ Exchange *Bitswap
70
blockstore blockstore.Blockstore
71
72
blockstoreDelay delay.D
@@ -94,7 +99,7 @@ func session(ctx context.Context, net tn.Network, p testutil.Identity) Instance
99
100
const alwaysSendToPeer = true
101
97
- bs := New(ctx, p.ID(), adapter, bstore, alwaysSendToPeer)
102
+ bs := New(ctx, p.ID(), adapter, bstore, alwaysSendToPeer).(*Bitswap)
103
104
return Instance{
105
Peer: p.ID(),
exchange/bitswap/workers.go
+3
-3
@@ -70,9 +70,9 @@ func (bs *Bitswap) taskWorker(ctx context.Context) {
70
if !ok {
71
continue
72
}
73
- log.Event(ctx, "deliverBlocks", envelope.Message, envelope.Peer)
74
- bs.send(ctx, envelope.Peer, envelope.Message)
75
- envelope.Sent()
73
+
74
+ //log.Event(ctx, "deliverBlocks", envelope.Message, envelope.Peer)
75
+ bs.pm.SendBlock(envelope)
76
case <-ctx.Done():
77
return
78
}