@cryptotaxi247 / kubo / commits / 52cefb16c

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 }