add a global timeout flag for to be setting timeouts
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Jul 20, 2015 at 12:34 UTC
608300798745edbfb76d8572b37f2efa82e76d55
4 files changed
+38
-19
commands/http/handler.go
+28
-11
@@ -7,6 +7,7 @@ import (
7
"net/http"
8
"strconv"
9
"strings"
10
+ "time"
11
12
"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"
@@ -106,20 +107,36 @@ func (i internalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
107
http.Error(w, err.Error(), http.StatusInternalServerError)
108
return
109
}
109
- ctx, cancel := context.WithCancel(node.Context())
110
- defer cancel()
111
- /*
112
- TODO(cryptix): the next line looks very fishy to me..
113
- It looks like the the context for the command request beeing prepared here is shared across all incoming requests..
110
115
- I assume it really isn't because ServeHTTP() doesn't take a pointer receiver, but it's really subtule..
111
+ tout, found, err := req.Option("timeout").String()
112
+ if err != nil {
113
+ err = fmt.Errorf("error parsing timeout option: %s", err)
114
+ http.Error(w, err.Error(), http.StatusInternalServerError)
115
+ return
116
+ }
117
+
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
117
- Shouldn't the context be just put on the command request?
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
119
- ps: take note of the name clash - commands.Context != context.Context
120
- */
121
- i.ctx.Context = ctx
122
- req.SetContext(i.ctx)
136
+ //ps: take note of the name clash - commands.Context != context.Context
137
+ cmdctx := i.ctx
138
+ cmdctx.Context = ctx
139
+ req.SetContext(cmdctx)
140
141
// call the command
142
res := i.root.Call(req)
commands/option.go
+8
-5
@@ -154,22 +154,25 @@ func (ov OptionValue) String() (value string, found bool, err error) {
154
155
// Flag names
156
const (
157
- EncShort = "enc"
158
- EncLong = "encoding"
159
- RecShort = "r"
160
- RecLong = "recursive"
161
- ChanOpt = "stream-channels"
157
+ EncShort = "enc"
158
+ EncLong = "encoding"
159
+ RecShort = "r"
160
+ RecLong = "recursive"
161
+ ChanOpt = "stream-channels"
162
+ TimeoutOpt = "timeout"
163
)
164
165
// options that are used by this package
166
var OptionEncodingType = StringOption(EncShort, EncLong, "The encoding type the output should be encoded with (json, xml, or text)")
167
var OptionRecursivePath = BoolOption(RecShort, RecLong, "Add directory paths recursively")
168
var OptionStreamChannels = BoolOption(ChanOpt, "Stream channel output")
169
+var OptionTimeout = StringOption(TimeoutOpt, "set a global timeout on the command")
170
171
// global options, added to every command
172
var globalOptions = []Option{
173
OptionEncodingType,
174
OptionStreamChannels,
175
+ OptionTimeout,
176
}
177
178
// the above array of Options, wrapped in a Command
core/commands/block.go
+1
-2
@@ -9,7 +9,6 @@ import (
9
"strings"
10
11
mh "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
12
- "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
12
"github.com/ipfs/go-ipfs/blocks"
13
key "github.com/ipfs/go-ipfs/blocks/key"
14
cmds "github.com/ipfs/go-ipfs/commands"
@@ -178,7 +177,7 @@ func getBlockForKey(req cmds.Request, skey string) (*blocks.Block, error) {
177
}
178
179
k := key.Key(h)
181
- b, err := n.Blocks.GetBlock(context.TODO(), k)
180
+ b, err := n.Blocks.GetBlock(req.Context().Context, k)
181
if err != nil {
182
return nil, err
183
}
core/commands/ls.go
+1
-1
@@ -81,7 +81,7 @@ it contains, with the following format:
81
Links: make([]LsLink, len(dagnode.Links)),
82
}
83
for j, link := range dagnode.Links {
84
- ctx, cancel := context.WithTimeout(context.TODO(), time.Minute)
84
+ ctx, cancel := context.WithTimeout(req.Context().Context, time.Minute)
85
defer cancel()
86
link.Node, err = link.GetNode(ctx, node.DAG)
87
if err != nil {