make offline commands respect timeout
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Jul 20, 2015 at 14:34 UTC
f9f3c6a5277811ed9d0117535461156c54980419
6 files changed
+41
-31
cmd/ipfs/main.go
+7
@@ -335,6 +335,13 @@ func callCommand(ctx context.Context, req cmds.Request, root *cmds.Command, cmd
335
} else {
336
log.Debug("Executing command locally")
337
338
+ ctx, err := cmds.GetContext(ctx, req)
339
+ if err != nil {
340
+ return nil, err
341
+ }
342
+
343
+ req.Context().Context = ctx
344
+
345
// Okay!!!!! NOW we can call the command.
346
res = root.Call(req)
347
commands/http/handler.go
+1
-21
@@ -7,10 +7,8 @@ import (
7
"net/http"
8
"strconv"
9
"strings"
10
- "time"
10
11
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/rs/cors"
13
- context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
12
13
cmds "github.com/ipfs/go-ipfs/commands"
14
u "github.com/ipfs/go-ipfs/util"
@@ -108,31 +106,13 @@ func (i internalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
106
return
107
}
108
111
- tout, found, err := req.Option("timeout").String()
109
+ ctx, err := cmds.GetContext(node.Context(), req)
110
if err != nil {
111
err = fmt.Errorf("error parsing timeout option: %s", err)
112
http.Error(w, err.Error(), http.StatusInternalServerError)
113
return
114
}
115
118
- var ctx context.Context
119
- if found {
120
- duration, err := time.ParseDuration(tout)
121
- if err != nil {
122
- err = fmt.Errorf("error parsing timeout option: %s", err)
123
- http.Error(w, err.Error(), http.StatusInternalServerError)
124
- return
125
- }
126
-
127
- tctx, cancel := context.WithTimeout(node.Context(), duration)
128
- defer cancel()
129
- ctx = tctx
130
- } else {
131
- cctx, cancel := context.WithCancel(node.Context())
132
- defer cancel()
133
- ctx = cctx
134
- }
135
-
116
//ps: take note of the name clash - commands.Context != context.Context
117
cmdctx := i.ctx
118
cmdctx.Context = ctx
commands/request.go
+23
@@ -7,6 +7,7 @@ import (
7
"os"
8
"reflect"
9
"strconv"
10
+ "time"
11
12
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
13
"github.com/ipfs/go-ipfs/commands/files"
@@ -297,3 +298,25 @@ func NewRequest(path []string, opts OptMap, args []string, file files.File, cmd
298
299
return req, nil
300
}
301
+
302
+func GetContext(base context.Context, req Request) (context.Context, error) {
303
+ tout, found, err := req.Option("timeout").String()
304
+ if err != nil {
305
+ return nil, fmt.Errorf("error parsing timeout option: %s", err)
306
+ }
307
+
308
+ var ctx context.Context
309
+ if found {
310
+ duration, err := time.ParseDuration(tout)
311
+ if err != nil {
312
+ return nil, fmt.Errorf("error parsing timeout option: %s", err)
313
+ }
314
+
315
+ tctx, _ := context.WithTimeout(base, duration)
316
+ ctx = tctx
317
+ } else {
318
+ cctx, _ := context.WithCancel(base)
319
+ ctx = cctx
320
+ }
321
+ return ctx, nil
322
+}
core/commands/pin.go
+7
-2
@@ -60,7 +60,12 @@ on disk.
60
recursive = false
61
}
62
63
- added, err := corerepo.Pin(n, req.Arguments(), recursive)
63
+ go func() {
64
+ <-req.Context().Context.Done()
65
+ log.Error("CONTEXT IS OVER!")
66
+ }()
67
+
68
+ added, err := corerepo.Pin(n, req.Context().Context, req.Arguments(), recursive)
69
if err != nil {
70
res.SetError(err, cmds.ErrNormal)
71
return
@@ -125,7 +130,7 @@ collected if needed.
130
recursive = false // default
131
}
132
128
- removed, err := corerepo.Unpin(n, req.Arguments(), recursive)
133
+ removed, err := corerepo.Unpin(n, req.Context().Context, req.Arguments(), recursive)
134
if err != nil {
135
res.SetError(err, cmds.ErrNormal)
136
return
core/corerepo/pinning.go
+2
-7
@@ -25,10 +25,7 @@ import (
25
path "github.com/ipfs/go-ipfs/path"
26
)
27
28
-func Pin(n *core.IpfsNode, paths []string, recursive bool) ([]key.Key, error) {
29
- // TODO(cryptix): do we want a ctx as first param for (Un)Pin() as well, just like core.Resolve?
30
- ctx := n.Context()
31
-
28
+func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]key.Key, error) {
29
dagnodes := make([]*merkledag.Node, 0)
30
for _, fpath := range paths {
31
dagnode, err := core.Resolve(ctx, n, path.Path(fpath))
@@ -62,9 +59,7 @@ func Pin(n *core.IpfsNode, paths []string, recursive bool) ([]key.Key, error) {
59
return out, nil
60
}
61
65
-func Unpin(n *core.IpfsNode, paths []string, recursive bool) ([]key.Key, error) {
66
- // TODO(cryptix): do we want a ctx as first param for (Un)Pin() as well, just like core.Resolve?
67
- ctx := n.Context()
62
+func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]key.Key, error) {
63
64
dagnodes := make([]*merkledag.Node, 0)
65
for _, fpath := range paths {
test/sharness/t0081-repo-pinning.sh
+1
-1
@@ -242,7 +242,7 @@ test_expect_success "some are no longer there" '
242
243
test_expect_success "recursive pin fails without objects" '
244
ipfs pin rm "$HASH_DIR1" &&
245
- test_must_fail ipfs pin add -r "$HASH_DIR1" 2>err_expected8 &&
245
+ test_must_fail ipfs pin add -r "$HASH_DIR1" --timeout=500ms 2>err_expected8 &&
246
grep "context deadline exceeded" err_expected8
247
'
248