moved util/ctx to github.com/jbenet/go-context
License: MIT Signed-off-by: Juan Batiz-Benet <juan@benet.ai>
Juan Batiz-Benet committed
Jul 10, 2015 at 17:48 UTC
11937be180d1e7f269f753921474f18104c6e6dc
9 files changed
+103
-53
Godeps/Godeps.json
+8
-5
@@ -14,11 +14,6 @@
14
"Comment": "null-5",
15
"Rev": "75cd24fc2f2c2a2088577d12123ddee5f54e0675"
16
},
17
- {
18
- "ImportPath": "code.google.com/p/goprotobuf/proto",
19
- "Comment": "go.r60-152",
20
- "Rev": "36be16571e14f67e114bb0af619e5de2c1591679"
21
- },
17
{
18
"ImportPath": "github.com/ActiveState/tail",
19
"Rev": "068b72961a6bc5b4a82cf4fc14ccc724c0cfa73a"
@@ -137,6 +132,14 @@
132
"ImportPath": "github.com/jbenet/go-base58",
133
"Rev": "6237cf65f3a6f7111cd8a42be3590df99a66bc7d"
134
},
135
+ {
136
+ "ImportPath": "github.com/jbenet/go-context/frac",
137
+ "Rev": "d14ea06fba99483203c19d92cfcd13ebe73135f4"
138
+ },
139
+ {
140
+ "ImportPath": "github.com/jbenet/go-context/io",
141
+ "Rev": "d14ea06fba99483203c19d92cfcd13ebe73135f4"
142
+ },
143
{
144
"ImportPath": "github.com/jbenet/go-datastore",
145
"Rev": "7d6acaf7c0164c335f2ca4100f8fe30a7e2943dd"
Godeps/_workspace/src/github.com/jbenet/go-context/frac/fracctx.go
new
+62
@@ -0,0 +1,62 @@
1
+// Package ctxext provides multiple useful context constructors.
2
+package ctxext
3
+
4
+import (
5
+ "time"
6
+
7
+ context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
8
+)
9
+
10
+// WithDeadlineFraction returns a Context with a fraction of the
11
+// original context's timeout. This is useful in sequential pipelines
12
+// of work, where one might try options and fall back to others
13
+// depending on the time available, or failure to respond. For example:
14
+//
15
+// // getPicture returns a picture from our encrypted database
16
+// // we have a pipeline of multiple steps. we need to:
17
+// // - get the data from a database
18
+// // - decrypt it
19
+// // - apply many transforms
20
+// //
21
+// // we **know** that each step takes increasingly more time.
22
+// // The transforms are much more expensive than decryption, and
23
+// // decryption is more expensive than the database lookup.
24
+// // If our database takes too long (i.e. >0.2 of available time),
25
+// // there's no use in continuing.
26
+// func getPicture(ctx context.Context, key string) ([]byte, error) {
27
+// // fractional timeout contexts to the rescue!
28
+//
29
+// // try the database with 0.2 of remaining time.
30
+// ctx1, _ := ctxext.WithDeadlineFraction(ctx, 0.2)
31
+// val, err := db.Get(ctx1, key)
32
+// if err != nil {
33
+// return nil, err
34
+// }
35
+//
36
+// // try decryption with 0.3 of remaining time.
37
+// ctx2, _ := ctxext.WithDeadlineFraction(ctx, 0.3)
38
+// if val, err = decryptor.Decrypt(ctx2, val); err != nil {
39
+// return nil, err
40
+// }
41
+//
42
+// // try transforms with all remaining time. hopefully it's enough!
43
+// return transformer.Transform(ctx, val)
44
+// }
45
+//
46
+//
47
+func WithDeadlineFraction(ctx context.Context, fraction float64) (
48
+ context.Context, context.CancelFunc) {
49
+
50
+ d, found := ctx.Deadline()
51
+ if !found { // no deadline
52
+ return context.WithCancel(ctx)
53
+ }
54
+
55
+ left := d.Sub(time.Now())
56
+ if left < 0 { // already passed...
57
+ return context.WithCancel(ctx)
58
+ }
59
+
60
+ left = time.Duration(float64(left) * fraction)
61
+ return context.WithTimeout(ctx, left)
62
+}
Godeps/_workspace/src/github.com/jbenet/go-context/frac/fracctx_test.go
renamed
+4
-5
@@ -1,17 +1,16 @@
1
-package ctxutil
1
+package ctxext
2
3
import (
4
+ "os"
5
"testing"
6
"time"
7
7
- travis "github.com/ipfs/go-ipfs/util/testutil/ci/travis"
8
-
8
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
)
10
11
// this test is on the context tool itself, not our stuff. it's for sanity on ours.
12
func TestDeadline(t *testing.T) {
14
- if travis.IsRunning() {
13
+ if os.Getenv("TRAVIS") == "true" {
14
t.Skip("timeouts don't work reliably on travis")
15
}
16
@@ -43,7 +42,7 @@ func TestDeadlineFractionForever(t *testing.T) {
42
}
43
44
func TestDeadlineFractionHalf(t *testing.T) {
46
- if travis.IsRunning() {
45
+ if os.Getenv("TRAVIS") == "true" {
46
t.Skip("timeouts don't work reliably on travis")
47
}
48
Godeps/_workspace/src/github.com/jbenet/go-context/io/ctxio.go
renamed
+11
-1
@@ -1,4 +1,14 @@
1
-package ctxutil
1
+// Package ctxio provides io.Reader and io.Writer wrappers that
2
+// respect context.Contexts. Use these at the interface between
3
+// your context code and your io.
4
+//
5
+// WARNING: read the code. see how writes and reads will continue
6
+// until you cancel the io. Maybe this package should provide
7
+// versions of io.ReadCloser and io.WriteCloser that automatically
8
+// call .Close when the context expires. But for now -- since in my
9
+// use cases I have long-lived connections with ephemeral io wrappers
10
+// -- this has yet to be a need.
11
+package ctxio
12
13
import (
14
"io"
Godeps/_workspace/src/github.com/jbenet/go-context/io/ctxio_test.go
renamed
+3
-3
@@ -1,4 +1,4 @@
1
-package ctxutil
1
+package ctxio
2
3
import (
4
"bytes"
@@ -49,8 +49,8 @@ func TestReader(t *testing.T) {
49
}
50
51
func TestWriter(t *testing.T) {
52
- buf := new(bytes.Buffer)
53
- w := NewWriter(context.Background(), buf)
52
+ var buf bytes.Buffer
53
+ w := NewWriter(context.Background(), &buf)
54
55
// write three
56
n, err := w.Write([]byte("abc"))
diagnostics/diag.go
+5
-6
@@ -13,15 +13,14 @@ import (
13
14
ggio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/io"
15
proto "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
16
+ ctxio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-context/io"
17
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
17
-
18
pb "github.com/ipfs/go-ipfs/diagnostics/pb"
19
host "github.com/ipfs/go-ipfs/p2p/host"
20
inet "github.com/ipfs/go-ipfs/p2p/net"
21
peer "github.com/ipfs/go-ipfs/p2p/peer"
22
protocol "github.com/ipfs/go-ipfs/p2p/protocol"
23
util "github.com/ipfs/go-ipfs/util"
24
- ctxutil "github.com/ipfs/go-ipfs/util/ctx"
24
)
25
26
var log = util.Logger("diagnostics")
@@ -209,8 +208,8 @@ func (d *Diagnostics) getDiagnosticFromPeer(ctx context.Context, p peer.ID, pmes
208
return nil, err
209
}
210
212
- cr := ctxutil.NewReader(ctx, s) // ok to use. we defer close stream in this func
213
- cw := ctxutil.NewWriter(ctx, s) // ok to use. we defer close stream in this func
211
+ cr := ctxio.NewReader(ctx, s) // ok to use. we defer close stream in this func
212
+ cw := ctxio.NewWriter(ctx, s) // ok to use. we defer close stream in this func
213
r := ggio.NewDelimitedReader(cr, inet.MessageSizeMax)
214
w := ggio.NewDelimitedWriter(cw)
215
@@ -267,8 +266,8 @@ func newMessage(diagID string) *pb.Message {
266
267
func (d *Diagnostics) HandleMessage(ctx context.Context, s inet.Stream) error {
268
270
- cr := ctxutil.NewReader(ctx, s)
271
- cw := ctxutil.NewWriter(ctx, s)
269
+ cr := ctxio.NewReader(ctx, s)
270
+ cw := ctxio.NewWriter(ctx, s)
271
r := ggio.NewDelimitedReader(cr, inet.MessageSizeMax) // maxsize
272
w := ggio.NewDelimitedWriter(cw)
273
routing/dht/dht_net.go
+8
-9
@@ -4,13 +4,12 @@ import (
4
"errors"
5
"time"
6
7
+ ggio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/io"
8
+ ctxio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-context/io"
9
+ context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
10
inet "github.com/ipfs/go-ipfs/p2p/net"
11
peer "github.com/ipfs/go-ipfs/p2p/peer"
12
pb "github.com/ipfs/go-ipfs/routing/dht/pb"
10
- ctxutil "github.com/ipfs/go-ipfs/util/ctx"
11
-
12
- ggio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/io"
13
- context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
13
)
14
15
// handleNewStream implements the inet.StreamHandler
@@ -22,8 +21,8 @@ func (dht *IpfsDHT) handleNewMessage(s inet.Stream) {
21
defer s.Close()
22
23
ctx := dht.Context()
25
- cr := ctxutil.NewReader(ctx, s) // ok to use. we defer close stream in this func
26
- cw := ctxutil.NewWriter(ctx, s) // ok to use. we defer close stream in this func
24
+ cr := ctxio.NewReader(ctx, s) // ok to use. we defer close stream in this func
25
+ cw := ctxio.NewWriter(ctx, s) // ok to use. we defer close stream in this func
26
r := ggio.NewDelimitedReader(cr, inet.MessageSizeMax)
27
w := ggio.NewDelimitedWriter(cw)
28
mPeer := s.Conn().RemotePeer()
@@ -78,8 +77,8 @@ func (dht *IpfsDHT) sendRequest(ctx context.Context, p peer.ID, pmes *pb.Message
77
}
78
defer s.Close()
79
81
- cr := ctxutil.NewReader(ctx, s) // ok to use. we defer close stream in this func
82
- cw := ctxutil.NewWriter(ctx, s) // ok to use. we defer close stream in this func
80
+ cr := ctxio.NewReader(ctx, s) // ok to use. we defer close stream in this func
81
+ cw := ctxio.NewWriter(ctx, s) // ok to use. we defer close stream in this func
82
r := ggio.NewDelimitedReader(cr, inet.MessageSizeMax)
83
w := ggio.NewDelimitedWriter(cw)
84
@@ -116,7 +115,7 @@ func (dht *IpfsDHT) sendMessage(ctx context.Context, p peer.ID, pmes *pb.Message
115
}
116
defer s.Close()
117
119
- cw := ctxutil.NewWriter(ctx, s) // ok to use. we defer close stream in this func
118
+ cw := ctxio.NewWriter(ctx, s) // ok to use. we defer close stream in this func
119
w := ggio.NewDelimitedWriter(cw)
120
121
if err := w.WriteMsg(pmes); err != nil {
routing/dht/records.go
+2
-2
@@ -3,13 +3,13 @@ package dht
3
import (
4
"fmt"
5
6
+ ctxfrac "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-context/frac"
7
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
8
ci "github.com/ipfs/go-ipfs/p2p/crypto"
9
peer "github.com/ipfs/go-ipfs/p2p/peer"
10
routing "github.com/ipfs/go-ipfs/routing"
11
pb "github.com/ipfs/go-ipfs/routing/dht/pb"
12
record "github.com/ipfs/go-ipfs/routing/record"
12
- ctxutil "github.com/ipfs/go-ipfs/util/ctx"
13
)
14
15
func (dht *IpfsDHT) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) {
@@ -22,7 +22,7 @@ func (dht *IpfsDHT) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, err
22
}
23
24
// ok, try the node itself. if they're overwhelmed or slow we can move on.
25
- ctxT, cancelFunc := ctxutil.WithDeadlineFraction(ctx, 0.3)
25
+ ctxT, cancelFunc := ctxfrac.WithDeadlineFraction(ctx, 0.3)
26
defer cancelFunc()
27
if pk, err := dht.getPublicKeyFromNode(ctx, p); err == nil {
28
err := dht.peerstore.AddPubKey(p, pk)
util/ctx/fracctx.go
deleted
-22
@@ -1,22 +0,0 @@
1
-package ctxutil
2
-
3
-import (
4
- "time"
5
-
6
- context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
7
-)
8
-
9
-func WithDeadlineFraction(ctx context.Context, fraction float64) (context.Context, context.CancelFunc) {
10
- d, found := ctx.Deadline()
11
- if !found { // no deadline
12
- return context.WithCancel(ctx)
13
- }
14
-
15
- left := d.Sub(time.Now())
16
- if left < 0 { // already passed...
17
- return context.WithCancel(ctx)
18
- }
19
-
20
- left = time.Duration(float64(left) * fraction)
21
- return context.WithTimeout(ctx, left)
22
-}