@cryptotaxi247 / kubo / commits / a159e6825

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 }