Routing uses context now
@perfmode boom
Juan Batiz-Benet committed
Sep 21, 2014 at 18:04 UTC
52cefb16cd7184ddffe15cd58e85f607e19c37dc
7 files changed
+95
-44
exchange/bitswap/bitswap.go
+1
-1
@@ -103,7 +103,7 @@ func (bs *bitswap) Block(parent context.Context, k u.Key) (*blocks.Block, error)
103
// it to peers (Partners) whose WantLists include it.
104
func (bs *bitswap) HasBlock(ctx context.Context, blk blocks.Block) error {
105
bs.sendToPeersThatWant(ctx, blk)
106
- return bs.routing.Provide(blk.Key())
106
+ return bs.routing.Provide(ctx, blk.Key())
107
}
108
109
// TODO(brian): handle errors
exchange/bitswap/network/interface.go
+1
-1
@@ -49,5 +49,5 @@ type Routing interface {
49
FindProvidersAsync(context.Context, u.Key, int) <-chan *peer.Peer
50
51
// Provide provides the key to the network
52
- Provide(key u.Key) error
52
+ Provide(context.Context, u.Key) error
53
}
routing/dht/dht.go
+4
-4
@@ -73,7 +73,7 @@ func NewDHT(p *peer.Peer, ps peer.Peerstore, net inet.Network, sender inet.Sende
73
}
74
75
// Connect to a new peer at the given address, ping and add to the routing table
76
-func (dht *IpfsDHT) Connect(npeer *peer.Peer) (*peer.Peer, error) {
76
+func (dht *IpfsDHT) Connect(ctx context.Context, npeer *peer.Peer) (*peer.Peer, error) {
77
u.DOut("Connect to new peer: %s\n", npeer.ID.Pretty())
78
79
// TODO(jbenet,whyrusleeping)
@@ -92,7 +92,7 @@ func (dht *IpfsDHT) Connect(npeer *peer.Peer) (*peer.Peer, error) {
92
93
// Ping new peer to register in their routing table
94
// NOTE: this should be done better...
95
- err = dht.Ping(npeer, time.Second*2)
95
+ err = dht.Ping(ctx, npeer)
96
if err != nil {
97
return nil, fmt.Errorf("failed to ping newly connected peer: %s\n", err)
98
}
@@ -497,8 +497,8 @@ func (dht *IpfsDHT) loadProvidableKeys() error {
497
}
498
499
// Bootstrap builds up list of peers by requesting random peer IDs
500
-func (dht *IpfsDHT) Bootstrap() {
500
+func (dht *IpfsDHT) Bootstrap(ctx context.Context) {
501
id := make([]byte, 16)
502
rand.Read(id)
503
- dht.FindPeer(peer.ID(id), time.Second*10)
503
+ dht.FindPeer(ctx, peer.ID(id))
504
}
routing/dht/dht_test.go
+68
-6
@@ -22,7 +22,7 @@ import (
22
)
23
24
func setupDHT(t *testing.T, p *peer.Peer) *IpfsDHT {
25
- ctx, _ := context.WithCancel(context.TODO())
25
+ ctx := context.Background()
26
27
peerstore := peer.NewPeerstore()
28
@@ -150,9 +150,11 @@ func TestValueGetSet(t *testing.T) {
150
t.Fatal(err)
151
}
152
153
- dhtA.PutValue("hello", []byte("world"))
153
+ ctxT, _ := context.WithTimeout(context.Background(), time.Second)
154
+ dhtA.PutValue(ctxT, "hello", []byte("world"))
155
155
- val, err := dhtA.GetValue("hello", time.Second*2)
156
+ ctxT, _ = context.WithTimeout(context.Background(), time.Second*2)
157
+ val, err := dhtA.GetValue(ctxT, "hello")
158
if err != nil {
159
t.Fatal(err)
160
}
@@ -208,7 +210,8 @@ func TestProvides(t *testing.T) {
210
211
time.Sleep(time.Millisecond * 60)
212
211
- provs, err := dhts[0].FindProviders(u.Key("hello"), time.Second)
213
+ ctxT, _ := context.WithTimeout(context.Background(), time.Second)
214
+ provs, err := dhts[0].FindProviders(ctxT, u.Key("hello"))
215
if err != nil {
216
t.Fatal(err)
217
}
@@ -218,6 +221,63 @@ func TestProvides(t *testing.T) {
221
}
222
}
223
224
+func TestProvidesAsync(t *testing.T) {
225
+ // t.Skip("skipping test to debug another")
226
+
227
+ u.Debug = false
228
+
229
+ _, peers, dhts := setupDHTS(4, t)
230
+ defer func() {
231
+ for i := 0; i < 4; i++ {
232
+ dhts[i].Halt()
233
+ defer dhts[i].network.Close()
234
+ }
235
+ }()
236
+
237
+ _, err := dhts[0].Connect(peers[1])
238
+ if err != nil {
239
+ t.Fatal(err)
240
+ }
241
+
242
+ _, err = dhts[1].Connect(peers[2])
243
+ if err != nil {
244
+ t.Fatal(err)
245
+ }
246
+
247
+ _, err = dhts[1].Connect(peers[3])
248
+ if err != nil {
249
+ t.Fatal(err)
250
+ }
251
+
252
+ err = dhts[3].putLocal(u.Key("hello"), []byte("world"))
253
+ if err != nil {
254
+ t.Fatal(err)
255
+ }
256
+
257
+ bits, err := dhts[3].getLocal(u.Key("hello"))
258
+ if err != nil && bytes.Equal(bits, []byte("world")) {
259
+ t.Fatal(err)
260
+ }
261
+
262
+ err = dhts[3].Provide(u.Key("hello"))
263
+ if err != nil {
264
+ t.Fatal(err)
265
+ }
266
+
267
+ time.Sleep(time.Millisecond * 60)
268
+
269
+ ctx, _ := context.WithTimeout(context.TODO(), time.Millisecond*300)
270
+ provs := dhts[0].FindProvidersAsync(ctx, u.Key("hello"), 5)
271
+ select {
272
+ case p := <-provs:
273
+ if !p.ID.Equal(dhts[3].self.ID) {
274
+ t.Fatalf("got a provider, but not the right one. %v", p.ID.Pretty())
275
+ }
276
+ case <-ctx.Done():
277
+ t.Fatal("Didnt get back providers")
278
+ }
279
+}
280
+
281
func TestLayeredGet(t *testing.T) {
282
// t.Skip("skipping test to debug another")
283
@@ -257,7 +317,8 @@ func TestLayeredGet(t *testing.T) {
317
318
time.Sleep(time.Millisecond * 60)
319
260
- val, err := dhts[0].GetValue(u.Key("hello"), time.Second)
320
+ ctxT, _ := context.WithTimeout(context.Background(), time.Second)
321
+ val, err := dhts[0].GetValue(ctxT, u.Key("hello"))
322
if err != nil {
323
t.Fatal(err)
324
}
@@ -296,7 +357,8 @@ func TestFindPeer(t *testing.T) {
357
t.Fatal(err)
358
}
359
299
- p, err := dhts[0].FindPeer(peers[2].ID, time.Second)
360
+ ctxT, _ := context.WithTimeout(context.Background(), time.Second)
361
+ p, err := dhts[0].FindPeer(ctxT, peers[2].ID)
362
if err != nil {
363
t.Fatal(err)
364
}
routing/dht/ext_test.go
+8
-4
@@ -108,7 +108,8 @@ func TestGetFailures(t *testing.T) {
108
109
// This one should time out
110
// u.POut("Timout Test\n")
111
- _, err := d.GetValue(u.Key("test"), time.Millisecond*10)
111
+ ctx1, _ := context.WithTimeout(context.Background(), time.Second)
112
+ _, err := d.GetValue(ctx1, u.Key("test"))
113
if err != nil {
114
if err != context.DeadlineExceeded {
115
t.Fatal("Got different error than we expected", err)
@@ -134,7 +135,8 @@ func TestGetFailures(t *testing.T) {
135
})
136
137
// This one should fail with NotFound
137
- _, err = d.GetValue(u.Key("test"), time.Millisecond*1000)
138
+ ctx2, _ := context.WithTimeout(context.Background(), time.Second)
139
+ _, err = d.GetValue(ctx2, u.Key("test"))
140
if err != nil {
141
if err != u.ErrNotFound {
142
t.Fatalf("Expected ErrNotFound, got: %s", err)
@@ -236,7 +238,8 @@ func TestNotFound(t *testing.T) {
238
239
})
240
239
- v, err := d.GetValue(u.Key("hello"), time.Second*5)
241
+ ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
242
+ v, err := d.GetValue(ctx, u.Key("hello"))
243
u.DOut("get value got %v\n", v)
244
if err != nil {
245
switch err {
@@ -299,7 +302,8 @@ func TestLessThanKResponses(t *testing.T) {
302
303
})
304
302
- _, err := d.GetValue(u.Key("hello"), time.Second*30)
305
+ ctx, _ := context.WithTimeout(context.Background(), time.Second*30)
306
+ _, err := d.GetValue(ctx, u.Key("hello"))
307
if err != nil {
308
switch err {
309
case u.ErrNotFound:
routing/dht/routing.go
+8
-21
@@ -3,7 +3,6 @@ package dht
3
import (
4
"bytes"
5
"encoding/json"
6
- "time"
6
7
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
@@ -18,9 +17,7 @@ import (
17
18
// PutValue adds value corresponding to given Key.
19
// This is the top level "Store" operation of the DHT
21
-func (dht *IpfsDHT) PutValue(key u.Key, value []byte) error {
22
- ctx := context.TODO()
23
-
20
+func (dht *IpfsDHT) PutValue(ctx context.Context, key u.Key, value []byte) error {
21
peers := []*peer.Peer{}
22
23
// get the peers we need to announce to
@@ -46,12 +43,10 @@ func (dht *IpfsDHT) PutValue(key u.Key, value []byte) error {
43
// GetValue searches for the value corresponding to given Key.
44
// If the search does not succeed, a multiaddr string of a closer peer is
45
// returned along with util.ErrSearchIncomplete
49
-func (dht *IpfsDHT) GetValue(key u.Key, timeout time.Duration) ([]byte, error) {
46
+func (dht *IpfsDHT) GetValue(ctx context.Context, key u.Key) ([]byte, error) {
47
ll := startNewRPC("GET")
48
defer ll.EndAndPrint()
49
53
- ctx, _ := context.WithTimeout(context.TODO(), timeout)
54
-
50
// If we have it local, dont bother doing an RPC!
51
// NOTE: this might not be what we want to do...
52
val, err := dht.getLocal(key)
@@ -101,8 +96,7 @@ func (dht *IpfsDHT) GetValue(key u.Key, timeout time.Duration) ([]byte, error) {
96
// This is what DSHTs (Coral and MainlineDHT) do to store large values in a DHT.
97
98
// Provide makes this node announce that it can provide a value for the given key
104
-func (dht *IpfsDHT) Provide(key u.Key) error {
105
- ctx := context.TODO()
99
+func (dht *IpfsDHT) Provide(ctx context.Context, key u.Key) error {
100
101
dht.providers.AddProvider(key, dht.self)
102
peers := dht.routingTables[0].NearestPeers(kb.ConvertKey(key), PoolSize)
@@ -174,12 +168,10 @@ func (dht *IpfsDHT) addPeerListAsync(k u.Key, peers []*Message_Peer, ps *peerSet
168
}
169
170
// FindProviders searches for peers who can provide the value for given key.
177
-func (dht *IpfsDHT) FindProviders(key u.Key, timeout time.Duration) ([]*peer.Peer, error) {
171
+func (dht *IpfsDHT) FindProviders(ctx context.Context, key u.Key) ([]*peer.Peer, error) {
172
ll := startNewRPC("FindProviders")
173
ll.EndAndPrint()
174
181
- ctx, _ := context.WithTimeout(context.TODO(), timeout)
182
-
175
// get closest peer
176
u.DOut("Find providers for: '%s'\n", key)
177
p := dht.routingTables[0].NearestPeer(kb.ConvertKey(key))
@@ -223,8 +215,7 @@ func (dht *IpfsDHT) FindProviders(key u.Key, timeout time.Duration) ([]*peer.Pee
215
// Find specific Peer
216
217
// FindPeer searches for a peer with given ID.
226
-func (dht *IpfsDHT) FindPeer(id peer.ID, timeout time.Duration) (*peer.Peer, error) {
227
- ctx, _ := context.WithTimeout(context.TODO(), timeout)
218
+func (dht *IpfsDHT) FindPeer(ctx context.Context, id peer.ID) (*peer.Peer, error) {
219
220
// Check if were already connected to them
221
p, _ := dht.Find(id)
@@ -266,8 +257,7 @@ func (dht *IpfsDHT) FindPeer(id peer.ID, timeout time.Duration) (*peer.Peer, err
257
return nil, u.ErrNotFound
258
}
259
269
-func (dht *IpfsDHT) findPeerMultiple(id peer.ID, timeout time.Duration) (*peer.Peer, error) {
270
- ctx, _ := context.WithTimeout(context.TODO(), timeout)
260
+func (dht *IpfsDHT) findPeerMultiple(ctx context.Context, id peer.ID) (*peer.Peer, error) {
261
262
// Check if were already connected to them
263
p, _ := dht.Find(id)
@@ -325,9 +315,7 @@ func (dht *IpfsDHT) findPeerMultiple(id peer.ID, timeout time.Duration) (*peer.P
315
}
316
317
// Ping a peer, log the time it took
328
-func (dht *IpfsDHT) Ping(p *peer.Peer, timeout time.Duration) error {
329
- ctx, _ := context.WithTimeout(context.TODO(), timeout)
330
-
318
+func (dht *IpfsDHT) Ping(ctx context.Context, p *peer.Peer) error {
319
// Thoughts: maybe this should accept an ID and do a peer lookup?
320
u.DOut("Enter Ping.\n")
321
@@ -336,8 +324,7 @@ func (dht *IpfsDHT) Ping(p *peer.Peer, timeout time.Duration) error {
324
return err
325
}
326
339
-func (dht *IpfsDHT) getDiagnostic(timeout time.Duration) ([]*diagInfo, error) {
340
- ctx, _ := context.WithTimeout(context.TODO(), timeout)
327
+func (dht *IpfsDHT) getDiagnostic(ctx context.Context) ([]*diagInfo, error) {
328
329
u.DOut("Begin Diagnostic")
330
peers := dht.routingTables[0].NearestPeers(kb.ConvertPeerID(dht.self.ID), 10)
routing/routing.go
+5
-7
@@ -1,8 +1,6 @@
1
package routing
2
3
import (
4
- "time"
5
-
4
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5
6
peer "github.com/jbenet/go-ipfs/peer"
@@ -17,22 +15,22 @@ type IpfsRouting interface {
15
// Basic Put/Get
16
17
// PutValue adds value corresponding to given Key.
20
- PutValue(key u.Key, value []byte) error
18
+ PutValue(context.Context, u.Key, []byte) error
19
20
// GetValue searches for the value corresponding to given Key.
23
- GetValue(key u.Key, timeout time.Duration) ([]byte, error)
21
+ GetValue(context.Context, u.Key) ([]byte, error)
22
23
// Value provider layer of indirection.
24
// This is what DSHTs (Coral and MainlineDHT) do to store large values in a DHT.
25
26
// Announce that this node can provide value for given key
29
- Provide(key u.Key) error
27
+ Provide(context.Context, u.Key) error
28
29
// FindProviders searches for peers who can provide the value for given key.
32
- FindProviders(key u.Key, timeout time.Duration) ([]*peer.Peer, error)
30
+ FindProviders(context.Context, u.Key) ([]*peer.Peer, error)
31
32
// Find specific Peer
33
34
// FindPeer searches for a peer with given ID.
37
- FindPeer(id peer.ID, timeout time.Duration) (*peer.Peer, error)
35
+ FindPeer(context.Context, peer.ID) (*peer.Peer, error)
36
}