@cryptotaxi247 / kubo / commits / 035d600f2

Godeps: use in net + new multiaddr

Juan Batiz-Benet committed Sep 14, 2014 at 01:38 UTC 035d600f28886f40d2d5170809d0a0cb82afd194
16 files changed +1165 -22
Godeps/Godeps.json
+8 -3
@@ -1,6 +1,6 @@
1 {
2 "ImportPath": "github.com/jbenet/go-ipfs",
3 - "GoVersion": "go1.3.1",
3 + "GoVersion": "go1.3",
4 "Packages": [
5 "./..."
6 ],
@@ -19,6 +19,11 @@
19 "Comment": "null-219",
20 "Rev": "00a7d3b31bbab5795b4a51933c04fc2768242970"
21 },
22 + {
23 + "ImportPath": "code.google.com/p/go.net/context",
24 + "Comment": "null-144",
25 + "Rev": "ad01a6fcc8a19d3a4478c836895ffe883bd2ceab"
26 + },
27 {
28 "ImportPath": "code.google.com/p/gogoprotobuf/proto",
29 "Rev": "6c980277330804e94257ac7ef70a3adbe1641059"
@@ -55,8 +60,8 @@
60 },
61 {
62 "ImportPath": "github.com/jbenet/go-multiaddr",
58 - "Comment": "0.1.2",
59 - "Rev": "b90678896b52c3e5a4c8176805c6facc3fe3eb82"
63 + "Comment": "0.1.2-2-g0624ab3",
64 + "Rev": "0624ab3bf754d013585c5d07f0100ba34901a689"
65 },
66 {
67 "ImportPath": "github.com/jbenet/go-multihash",
Godeps/_workspace/src/code.google.com/p/go.net/context/context.go new
+431
@@ -0,0 +1,431 @@
1 +// Copyright 2014 The Go Authors. All rights reserved.
2 +// Use of this source code is governed by a BSD-style
3 +// license that can be found in the LICENSE file.
4 +
5 +// Package context defines the Context type, which carries deadlines,
6 +// cancelation signals, and other request-scoped values across API boundaries
7 +// and between processes.
8 +//
9 +// Incoming requests to a server should create a Context, and outgoing calls to
10 +// servers should accept a Context. The chain of function calls between must
11 +// propagate the Context, optionally replacing it with a modified copy created
12 +// using WithDeadline, WithTimeout, WithCancel, or WithValue.
13 +//
14 +// Programs that use Contexts should follow these rules to keep interfaces
15 +// consistent across packages and enable static analysis tools to check context
16 +// propagation:
17 +//
18 +// Do not store Contexts inside a struct type; instead, pass a Context
19 +// explicitly to each function that needs it. The Context should be the first
20 +// parameter, typically named ctx:
21 +//
22 +// func DoSomething(ctx context.Context, arg Arg) error {
23 +// // ... use ctx ...
24 +// }
25 +//
26 +// Do not pass a nil Context, even if a function permits it. Pass context.TODO
27 +// if you are unsure about which Context to use.
28 +//
29 +// Use context Values only for request-scoped data that transits processes and
30 +// APIs, not for passing optional parameters to functions.
31 +//
32 +// The same Context may be passed to functions running in different goroutines;
33 +// Contexts are safe for simultaneous use by multiple goroutines.
34 +//
35 +// See http://blog.golang.org/context for example code for a server that uses
36 +// Contexts.
37 +package context
38 +
39 +import (
40 + "errors"
41 + "fmt"
42 + "sync"
43 + "time"
44 +)
45 +
46 +// A Context carries a deadline, a cancelation signal, and other values across
47 +// API boundaries.
48 +//
49 +// Context's methods may be called by multiple goroutines simultaneously.
50 +type Context interface {
51 + // Deadline returns the time when work done on behalf of this context
52 + // should be canceled. Deadline returns ok==false when no deadline is
53 + // set. Successive calls to Deadline return the same results.
54 + Deadline() (deadline time.Time, ok bool)
55 +
56 + // Done returns a channel that's closed when work done on behalf of this
57 + // context should be canceled. Done may return nil if this context can
58 + // never be canceled. Successive calls to Done return the same value.
59 + //
60 + // WithCancel arranges for Done to be closed when cancel is called;
61 + // WithDeadline arranges for Done to be closed when the deadline
62 + // expires; WithTimeout arranges for Done to be closed when the timeout
63 + // elapses.
64 + //
65 + // Done is provided for use in select statements:
66 + //
67 + // // DoSomething calls DoSomethingSlow and returns as soon as
68 + // // it returns or ctx.Done is closed.
69 + // func DoSomething(ctx context.Context) (Result, error) {
70 + // c := make(chan Result, 1)
71 + // go func() { c <- DoSomethingSlow(ctx) }()
72 + // select {
73 + // case res := <-c:
74 + // return res, nil
75 + // case <-ctx.Done():
76 + // return nil, ctx.Err()
77 + // }
78 + // }
79 + //
80 + // See http://blog.golang.org/pipelines for more examples of how to use
81 + // a Done channel for cancelation.
82 + Done() <-chan struct{}
83 +
84 + // Err returns a non-nil error value after Done is closed. Err returns
85 + // Canceled if the context was canceled or DeadlineExceeded if the
86 + // context's deadline passed. No other values for Err are defined.
87 + // After Done is closed, successive calls to Err return the same value.
88 + Err() error
89 +
90 + // Value returns the value associated with this context for key, or nil
91 + // if no value is associated with key. Successive calls to Value with
92 + // the same key returns the same result.
93 + //
94 + // Use context values only for request-scoped data that transits
95 + // processes and API boundaries, not for passing optional parameters to
96 + // functions.
97 + //
98 + // A key identifies a specific value in a Context. Functions that wish
99 + // to store values in Context typically allocate a key in a global
100 + // variable then use that key as the argument to context.WithValue and
101 + // Context.Value. A key can be any type that supports equality;
102 + // packages should define keys as an unexported type to avoid
103 + // collisions.
104 + //
105 + // Packages that define a Context key should provide type-safe accessors
106 + // for the values stores using that key:
107 + //
108 + // // Package user defines a User type that's stored in Contexts.
109 + // package user
110 + //
111 + // import "code.google.com/p/go.net/context"
112 + //
113 + // // User is the type of value stored in the Contexts.
114 + // type User struct {...}
115 + //
116 + // // key is an unexported type for keys defined in this package.
117 + // // This prevents collisions with keys defined in other packages.
118 + // type key int
119 + //
120 + // // userKey is the key for user.User values in Contexts. It is
121 + // // unexported; clients use user.NewContext and user.FromContext
122 + // // instead of using this key directly.
123 + // var userKey key = 0
124 + //
125 + // // NewContext returns a new Context that carries value u.
126 + // func NewContext(ctx context.Context, u *User) context.Context {
127 + // return context.WithValue(userKey, u)
128 + // }
129 + //
130 + // // FromContext returns the User value stored in ctx, if any.
131 + // func FromContext(ctx context.Context) (*User, bool) {
132 + // u, ok := ctx.Value(userKey).(*User)
133 + // return u, ok
134 + // }
135 + Value(key interface{}) interface{}
136 +}
137 +
138 +// Canceled is the error returned by Context.Err when the context is canceled.
139 +var Canceled = errors.New("context canceled")
140 +
141 +// DeadlineExceeded is the error returned by Context.Err when the context's
142 +// deadline passes.
143 +var DeadlineExceeded = errors.New("context deadline exceeded")
144 +
145 +// An emptyCtx is never canceled, has no values, and has no deadline.
146 +type emptyCtx int
147 +
148 +func (emptyCtx) Deadline() (deadline time.Time, ok bool) {
149 + return
150 +}
151 +
152 +func (emptyCtx) Done() <-chan struct{} {
153 + return nil
154 +}
155 +
156 +func (emptyCtx) Err() error {
157 + return nil
158 +}
159 +
160 +func (emptyCtx) Value(key interface{}) interface{} {
161 + return nil
162 +}
163 +
164 +func (n emptyCtx) String() string {
165 + switch n {
166 + case background:
167 + return "context.Background"
168 + case todo:
169 + return "context.TODO"
170 + }
171 + return "unknown empty Context"
172 +}
173 +
174 +const (
175 + background emptyCtx = 1
176 + todo emptyCtx = 2
177 +)
178 +
179 +// Background returns a non-nil, empty Context. It is never canceled, has no
180 +// values, and has no deadline. It is typically used by the main function,
181 +// initialization, and tests, and as the top-level Context for incoming
182 +// requests.
183 +func Background() Context {
184 + return background
185 +}
186 +
187 +// TODO returns a non-nil, empty Context. Code should use context.TODO when
188 +// it's unclear which Context to use or it's is not yet available (because the
189 +// surrounding function has not yet been extended to accept a Context
190 +// parameter). TODO is recognized by static analysis tools that determine
191 +// whether Contexts are propagated correctly in a program.
192 +func TODO() Context {
193 + return todo
194 +}
195 +
196 +// A CancelFunc tells an operation to abandon its work.
197 +// A CancelFunc does not wait for the work to stop.
198 +// After the first call, subsequent calls to a CancelFunc do nothing.
199 +type CancelFunc func()
200 +
201 +// WithCancel returns a copy of parent with a new Done channel. The returned
202 +// context's Done channel is closed when the returned cancel function is called
203 +// or when the parent context's Done channel is closed, whichever happens first.
204 +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
205 + c := newCancelCtx(parent)
206 + propagateCancel(parent, &c)
207 + return &c, func() { c.cancel(true, Canceled) }
208 +}
209 +
210 +// newCancelCtx returns an initialized cancelCtx.
211 +func newCancelCtx(parent Context) cancelCtx {
212 + return cancelCtx{
213 + Context: parent,
214 + done: make(chan struct{}),
215 + }
216 +}
217 +
218 +// propagateCancel arranges for child to be canceled when parent is.
219 +func propagateCancel(parent Context, child canceler) {
220 + if parent.Done() == nil {
221 + return // parent is never canceled
222 + }
223 + if p, ok := parentCancelCtx(parent); ok {
224 + p.mu.Lock()
225 + if p.err != nil {
226 + // parent has already been canceled
227 + child.cancel(false, p.err)
228 + } else {
229 + if p.children == nil {
230 + p.children = make(map[canceler]bool)
231 + }
232 + p.children[child] = true
233 + }
234 + p.mu.Unlock()
235 + } else {
236 + go func() {
237 + select {
238 + case <-parent.Done():
239 + child.cancel(false, parent.Err())
240 + case <-child.Done():
241 + }
242 + }()
243 + }
244 +}
245 +
246 +// parentCancelCtx follows a chain of parent references until it finds a
247 +// *cancelCtx. This function understands how each of the concrete types in this
248 +// package represents its parent.
249 +func parentCancelCtx(parent Context) (*cancelCtx, bool) {
250 + for {
251 + switch c := parent.(type) {
252 + case *cancelCtx:
253 + return c, true
254 + case *timerCtx:
255 + return &c.cancelCtx, true
256 + case *valueCtx:
257 + parent = c.Context
258 + default:
259 + return nil, false
260 + }
261 + }
262 +}
263 +
264 +// A canceler is a context type that can be canceled directly. The
265 +// implementations are *cancelCtx and *timerCtx.
266 +type canceler interface {
267 + cancel(removeFromParent bool, err error)
268 + Done() <-chan struct{}
269 +}
270 +
271 +// A cancelCtx can be canceled. When canceled, it also cancels any children
272 +// that implement canceler.
273 +type cancelCtx struct {
274 + Context
275 +
276 + done chan struct{} // closed by the first cancel call.
277 +
278 + mu sync.Mutex
279 + children map[canceler]bool // set to nil by the first cancel call
280 + err error // set to non-nil by the first cancel call
281 +}
282 +
283 +func (c *cancelCtx) Done() <-chan struct{} {
284 + return c.done
285 +}
286 +
287 +func (c *cancelCtx) Err() error {
288 + c.mu.Lock()
289 + defer c.mu.Unlock()
290 + return c.err
291 +}
292 +
293 +func (c *cancelCtx) String() string {
294 + return fmt.Sprintf("%v.WithCancel", c.Context)
295 +}
296 +
297 +// cancel closes c.done, cancels each of c's children, and, if
298 +// removeFromParent is true, removes c from its parent's children.
299 +func (c *cancelCtx) cancel(removeFromParent bool, err error) {
300 + if err == nil {
301 + panic("context: internal error: missing cancel error")
302 + }
303 + c.mu.Lock()
304 + if c.err != nil {
305 + c.mu.Unlock()
306 + return // already canceled
307 + }
308 + c.err = err
309 + close(c.done)
310 + for child := range c.children {
311 + // NOTE: acquiring the child's lock while holding parent's lock.
312 + child.cancel(false, err)
313 + }
314 + c.children = nil
315 + c.mu.Unlock()
316 +
317 + if removeFromParent {
318 + if p, ok := parentCancelCtx(c.Context); ok {
319 + p.mu.Lock()
320 + if p.children != nil {
321 + delete(p.children, c)
322 + }
323 + p.mu.Unlock()
324 + }
325 + }
326 +}
327 +
328 +// WithDeadline returns a copy of the parent context with the deadline adjusted
329 +// to be no later than d. If the parent's deadline is already earlier than d,
330 +// WithDeadline(parent, d) is semantically equivalent to parent. The returned
331 +// context's Done channel is closed when the deadline expires, when the returned
332 +// cancel function is called, or when the parent context's Done channel is
333 +// closed, whichever happens first.
334 +//
335 +// Canceling this context releases resources associated with the deadline
336 +// timer, so code should call cancel as soon as the operations running in this
337 +// Context complete.
338 +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
339 + if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
340 + // The current deadline is already sooner than the new one.
341 + return WithCancel(parent)
342 + }
343 + c := &timerCtx{
344 + cancelCtx: newCancelCtx(parent),
345 + deadline: deadline,
346 + }
347 + propagateCancel(parent, c)
348 + d := deadline.Sub(time.Now())
349 + if d <= 0 {
350 + c.cancel(true, DeadlineExceeded) // deadline has already passed
351 + return c, func() { c.cancel(true, Canceled) }
352 + }
353 + c.mu.Lock()
354 + defer c.mu.Unlock()
355 + if c.err == nil {
356 + c.timer = time.AfterFunc(d, func() {
357 + c.cancel(true, DeadlineExceeded)
358 + })
359 + }
360 + return c, func() { c.cancel(true, Canceled) }
361 +}
362 +
363 +// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
364 +// implement Done and Err. It implements cancel by stopping its timer then
365 +// delegating to cancelCtx.cancel.
366 +type timerCtx struct {
367 + cancelCtx
368 + timer *time.Timer // Under cancelCtx.mu.
369 +
370 + deadline time.Time
371 +}
372 +
373 +func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
374 + return c.deadline, true
375 +}
376 +
377 +func (c *timerCtx) String() string {
378 + return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
379 +}
380 +
381 +func (c *timerCtx) cancel(removeFromParent bool, err error) {
382 + c.cancelCtx.cancel(removeFromParent, err)
383 + c.mu.Lock()
384 + if c.timer != nil {
385 + c.timer.Stop()
386 + c.timer = nil
387 + }
388 + c.mu.Unlock()
389 +}
390 +
391 +// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
392 +//
393 +// Canceling this context releases resources associated with the deadline
394 +// timer, so code should call cancel as soon as the operations running in this
395 +// Context complete:
396 +//
397 +// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
398 +// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
399 +// defer cancel() // releases resources if slowOperation completes before timeout elapses
400 +// return slowOperation(ctx)
401 +// }
402 +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
403 + return WithDeadline(parent, time.Now().Add(timeout))
404 +}
405 +
406 +// WithValue returns a copy of parent in which the value associated with key is
407 +// val.
408 +//
409 +// Use context Values only for request-scoped data that transits processes and
410 +// APIs, not for passing optional parameters to functions.
411 +func WithValue(parent Context, key interface{}, val interface{}) Context {
412 + return &valueCtx{parent, key, val}
413 +}
414 +
415 +// A valueCtx carries a key-value pair. It implements Value for that key and
416 +// delegates all other calls to the embedded Context.
417 +type valueCtx struct {
418 + Context
419 + key, val interface{}
420 +}
421 +
422 +func (c *valueCtx) String() string {
423 + return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
424 +}
425 +
426 +func (c *valueCtx) Value(key interface{}) interface{} {
427 + if c.key == key {
428 + return c.val
429 + }
430 + return c.Context.Value(key)
431 +}
Godeps/_workspace/src/code.google.com/p/go.net/context/context_test.go new
+553
@@ -0,0 +1,553 @@
1 +// Copyright 2014 The Go Authors. All rights reserved.
2 +// Use of this source code is governed by a BSD-style
3 +// license that can be found in the LICENSE file.
4 +
5 +package context
6 +
7 +import (
8 + "fmt"
9 + "math/rand"
10 + "runtime"
11 + "strings"
12 + "sync"
13 + "testing"
14 + "time"
15 +)
16 +
17 +// otherContext is a Context that's not one of the types defined in context.go.
18 +// This lets us test code paths that differ based on the underlying type of the
19 +// Context.
20 +type otherContext struct {
21 + Context
22 +}
23 +
24 +func TestBackground(t *testing.T) {
25 + c := Background()
26 + if c == nil {
27 + t.Fatalf("Background returned nil")
28 + }
29 + select {
30 + case x := <-c.Done():
31 + t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
32 + default:
33 + }
34 + if got, want := fmt.Sprint(c), "context.Background"; got != want {
35 + t.Errorf("Background().String() = %q want %q", got, want)
36 + }
37 +}
38 +
39 +func TestTODO(t *testing.T) {
40 + c := TODO()
41 + if c == nil {
42 + t.Fatalf("TODO returned nil")
43 + }
44 + select {
45 + case x := <-c.Done():
46 + t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
47 + default:
48 + }
49 + if got, want := fmt.Sprint(c), "context.TODO"; got != want {
50 + t.Errorf("TODO().String() = %q want %q", got, want)
51 + }
52 +}
53 +
54 +func TestWithCancel(t *testing.T) {
55 + c1, cancel := WithCancel(Background())
56 +
57 + if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want {
58 + t.Errorf("c1.String() = %q want %q", got, want)
59 + }
60 +
61 + o := otherContext{c1}
62 + c2, _ := WithCancel(o)
63 + contexts := []Context{c1, o, c2}
64 +
65 + for i, c := range contexts {
66 + if d := c.Done(); d == nil {
67 + t.Errorf("c[%d].Done() == %v want non-nil", i, d)
68 + }
69 + if e := c.Err(); e != nil {
70 + t.Errorf("c[%d].Err() == %v want nil", i, e)
71 + }
72 +
73 + select {
74 + case x := <-c.Done():
75 + t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
76 + default:
77 + }
78 + }
79 +
80 + cancel()
81 + time.Sleep(100 * time.Millisecond) // let cancelation propagate
82 +
83 + for i, c := range contexts {
84 + select {
85 + case <-c.Done():
86 + default:
87 + t.Errorf("<-c[%d].Done() blocked, but shouldn't have", i)
88 + }
89 + if e := c.Err(); e != Canceled {
90 + t.Errorf("c[%d].Err() == %v want %v", i, e, Canceled)
91 + }
92 + }
93 +}
94 +
95 +func TestParentFinishesChild(t *testing.T) {
96 + // Context tree:
97 + // parent -> cancelChild
98 + // parent -> valueChild -> timerChild
99 + parent, cancel := WithCancel(Background())
100 + cancelChild, stop := WithCancel(parent)
101 + defer stop()
102 + valueChild := WithValue(parent, "key", "value")
103 + timerChild, stop := WithTimeout(valueChild, 10000*time.Hour)
104 + defer stop()
105 +
106 + select {
107 + case x := <-parent.Done():
108 + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
109 + case x := <-cancelChild.Done():
110 + t.Errorf("<-cancelChild.Done() == %v want nothing (it should block)", x)
111 + case x := <-timerChild.Done():
112 + t.Errorf("<-timerChild.Done() == %v want nothing (it should block)", x)
113 + case x := <-valueChild.Done():
114 + t.Errorf("<-valueChild.Done() == %v want nothing (it should block)", x)
115 + default:
116 + }
117 +
118 + // The parent's children should contain the two cancelable children.
119 + pc := parent.(*cancelCtx)
120 + cc := cancelChild.(*cancelCtx)
121 + tc := timerChild.(*timerCtx)
122 + pc.mu.Lock()
123 + if len(pc.children) != 2 || !pc.children[cc] || !pc.children[tc] {
124 + t.Errorf("bad linkage: pc.children = %v, want %v and %v",
125 + pc.children, cc, tc)
126 + }
127 + pc.mu.Unlock()
128 +
129 + if p, ok := parentCancelCtx(cc.Context); !ok || p != pc {
130 + t.Errorf("bad linkage: parentCancelCtx(cancelChild.Context) = %v, %v want %v, true", p, ok, pc)
131 + }
132 + if p, ok := parentCancelCtx(tc.Context); !ok || p != pc {
133 + t.Errorf("bad linkage: parentCancelCtx(timerChild.Context) = %v, %v want %v, true", p, ok, pc)
134 + }
135 +
136 + cancel()
137 +
138 + pc.mu.Lock()
139 + if len(pc.children) != 0 {
140 + t.Errorf("pc.cancel didn't clear pc.children = %v", pc.children)
141 + }
142 + pc.mu.Unlock()
143 +
144 + // parent and children should all be finished.
145 + check := func(ctx Context, name string) {
146 + select {
147 + case <-ctx.Done():
148 + default:
149 + t.Errorf("<-%s.Done() blocked, but shouldn't have", name)
150 + }
151 + if e := ctx.Err(); e != Canceled {
152 + t.Errorf("%s.Err() == %v want %v", name, e, Canceled)
153 + }
154 + }
155 + check(parent, "parent")
156 + check(cancelChild, "cancelChild")
157 + check(valueChild, "valueChild")
158 + check(timerChild, "timerChild")
159 +
160 + // WithCancel should return a canceled context on a canceled parent.
161 + precanceledChild := WithValue(parent, "key", "value")
162 + select {
163 + case <-precanceledChild.Done():
164 + default:
165 + t.Errorf("<-precanceledChild.Done() blocked, but shouldn't have")
166 + }
167 + if e := precanceledChild.Err(); e != Canceled {
168 + t.Errorf("precanceledChild.Err() == %v want %v", e, Canceled)
169 + }
170 +}
171 +
172 +func TestChildFinishesFirst(t *testing.T) {
173 + cancelable, stop := WithCancel(Background())
174 + defer stop()
175 + for _, parent := range []Context{Background(), cancelable} {
176 + child, cancel := WithCancel(parent)
177 +
178 + select {
179 + case x := <-parent.Done():
180 + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
181 + case x := <-child.Done():
182 + t.Errorf("<-child.Done() == %v want nothing (it should block)", x)
183 + default:
184 + }
185 +
186 + cc := child.(*cancelCtx)
187 + pc, pcok := parent.(*cancelCtx) // pcok == false when parent == Background()
188 + if p, ok := parentCancelCtx(cc.Context); ok != pcok || (ok && pc != p) {
189 + t.Errorf("bad linkage: parentCancelCtx(cc.Context) = %v, %v want %v, %v", p, ok, pc, pcok)
190 + }
191 +
192 + if pcok {
193 + pc.mu.Lock()
194 + if len(pc.children) != 1 || !pc.children[cc] {
195 + t.Errorf("bad linkage: pc.children = %v, cc = %v", pc.children, cc)
196 + }
197 + pc.mu.Unlock()
198 + }
199 +
200 + cancel()
201 +
202 + if pcok {
203 + pc.mu.Lock()
204 + if len(pc.children) != 0 {
205 + t.Errorf("child's cancel didn't remove self from pc.children = %v", pc.children)
206 + }
207 + pc.mu.Unlock()
208 + }
209 +
210 + // child should be finished.
211 + select {
212 + case <-child.Done():
213 + default:
214 + t.Errorf("<-child.Done() blocked, but shouldn't have")
215 + }
216 + if e := child.Err(); e != Canceled {
217 + t.Errorf("child.Err() == %v want %v", e, Canceled)
218 + }
219 +
220 + // parent should not be finished.
221 + select {
222 + case x := <-parent.Done():
223 + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
224 + default:
225 + }
226 + if e := parent.Err(); e != nil {
227 + t.Errorf("parent.Err() == %v want nil", e)
228 + }
229 + }
230 +}
231 +
232 +func testDeadline(c Context, wait time.Duration, t *testing.T) {
233 + select {
234 + case <-time.After(wait):
235 + t.Fatalf("context should have timed out")
236 + case <-c.Done():
237 + }
238 + if e := c.Err(); e != DeadlineExceeded {
239 + t.Errorf("c.Err() == %v want %v", e, DeadlineExceeded)
240 + }
241 +}
242 +
243 +func TestDeadline(t *testing.T) {
244 + c, _ := WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
245 + if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
246 + t.Errorf("c.String() = %q want prefix %q", got, prefix)
247 + }
248 + testDeadline(c, 200*time.Millisecond, t)
249 +
250 + c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
251 + o := otherContext{c}
252 + testDeadline(o, 200*time.Millisecond, t)
253 +
254 + c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
255 + o = otherContext{c}
256 + c, _ = WithDeadline(o, time.Now().Add(300*time.Millisecond))
257 + testDeadline(c, 200*time.Millisecond, t)
258 +}
259 +
260 +func TestTimeout(t *testing.T) {
261 + c, _ := WithTimeout(Background(), 100*time.Millisecond)
262 + if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
263 + t.Errorf("c.String() = %q want prefix %q", got, prefix)
264 + }
265 + testDeadline(c, 200*time.Millisecond, t)
266 +
267 + c, _ = WithTimeout(Background(), 100*time.Millisecond)
268 + o := otherContext{c}
269 + testDeadline(o, 200*time.Millisecond, t)
270 +
271 + c, _ = WithTimeout(Background(), 100*time.Millisecond)
272 + o = otherContext{c}
273 + c, _ = WithTimeout(o, 300*time.Millisecond)
274 + testDeadline(c, 200*time.Millisecond, t)
275 +}
276 +
277 +func TestCanceledTimeout(t *testing.T) {
278 + c, _ := WithTimeout(Background(), 200*time.Millisecond)
279 + o := otherContext{c}
280 + c, cancel := WithTimeout(o, 400*time.Millisecond)
281 + cancel()
282 + time.Sleep(100 * time.Millisecond) // let cancelation propagate
283 + select {
284 + case <-c.Done():
285 + default:
286 + t.Errorf("<-c.Done() blocked, but shouldn't have")
287 + }
288 + if e := c.Err(); e != Canceled {
289 + t.Errorf("c.Err() == %v want %v", e, Canceled)
290 + }
291 +}
292 +
293 +type key1 int
294 +type key2 int
295 +
296 +var k1 = key1(1)
297 +var k2 = key2(1) // same int as k1, different type
298 +var k3 = key2(3) // same type as k2, different int
299 +
300 +func TestValues(t *testing.T) {
301 + check := func(c Context, nm, v1, v2, v3 string) {
302 + if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 {
303 + t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0)
304 + }
305 + if v, ok := c.Value(k2).(string); ok == (len(v2) == 0) || v != v2 {
306 + t.Errorf(`%s.Value(k2).(string) = %q, %t want %q, %t`, nm, v, ok, v2, len(v2) != 0)
307 + }
308 + if v, ok := c.Value(k3).(string); ok == (len(v3) == 0) || v != v3 {
309 + t.Errorf(`%s.Value(k3).(string) = %q, %t want %q, %t`, nm, v, ok, v3, len(v3) != 0)
310 + }
311 + }
312 +
313 + c0 := Background()
314 + check(c0, "c0", "", "", "")
315 +
316 + c1 := WithValue(Background(), k1, "c1k1")
317 + check(c1, "c1", "c1k1", "", "")
318 +
319 + if got, want := fmt.Sprint(c1), `context.Background.WithValue(1, "c1k1")`; got != want {
320 + t.Errorf("c.String() = %q want %q", got, want)
321 + }
322 +
323 + c2 := WithValue(c1, k2, "c2k2")
324 + check(c2, "c2", "c1k1", "c2k2", "")
325 +
326 + c3 := WithValue(c2, k3, "c3k3")
327 + check(c3, "c2", "c1k1", "c2k2", "c3k3")
328 +
329 + c4 := WithValue(c3, k1, nil)
330 + check(c4, "c4", "", "c2k2", "c3k3")
331 +
332 + o0 := otherContext{Background()}
333 + check(o0, "o0", "", "", "")
334 +
335 + o1 := otherContext{WithValue(Background(), k1, "c1k1")}
336 + check(o1, "o1", "c1k1", "", "")
337 +
338 + o2 := WithValue(o1, k2, "o2k2")
339 + check(o2, "o2", "c1k1", "o2k2", "")
340 +
341 + o3 := otherContext{c4}
342 + check(o3, "o3", "", "c2k2", "c3k3")
343 +
344 + o4 := WithValue(o3, k3, nil)
345 + check(o4, "o4", "", "c2k2", "")
346 +}
347 +
348 +func TestAllocs(t *testing.T) {
349 + bg := Background()
350 + for _, test := range []struct {
351 + desc string
352 + f func()
353 + limit float64
354 + gccgoLimit float64
355 + }{
356 + {
357 + desc: "Background()",
358 + f: func() { Background() },
359 + limit: 0,
360 + gccgoLimit: 0,
361 + },
362 + {
363 + desc: fmt.Sprintf("WithValue(bg, %v, nil)", k1),
364 + f: func() {
365 + c := WithValue(bg, k1, nil)
366 + c.Value(k1)
367 + },
368 + limit: 1,
369 + gccgoLimit: 3,
370 + },
371 + {
372 + desc: "WithTimeout(bg, 15*time.Millisecond)",
373 + f: func() {
374 + c, _ := WithTimeout(bg, 15*time.Millisecond)
375 + <-c.Done()
376 + },
377 + limit: 8,
378 + gccgoLimit: 13,
379 + },
380 + {
381 + desc: "WithCancel(bg)",
382 + f: func() {
383 + c, cancel := WithCancel(bg)
384 + cancel()
385 + <-c.Done()
386 + },
387 + limit: 5,
388 + gccgoLimit: 8,
389 + },
390 + {
391 + desc: "WithTimeout(bg, 100*time.Millisecond)",
392 + f: func() {
393 + c, cancel := WithTimeout(bg, 100*time.Millisecond)
394 + cancel()
395 + <-c.Done()
396 + },
397 + limit: 8,
398 + gccgoLimit: 25,
399 + },
400 + } {
401 + limit := test.limit
402 + if runtime.Compiler == "gccgo" {
403 + // gccgo does not yet do escape analysis.
404 + // TOOD(iant): Remove this when gccgo does do escape analysis.
405 + limit = test.gccgoLimit
406 + }
407 + if n := testing.AllocsPerRun(100, test.f); n > limit {
408 + t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit))
409 + }
410 + }
411 +}
412 +
413 +func TestSimultaneousCancels(t *testing.T) {
414 + root, cancel := WithCancel(Background())
415 + m := map[Context]CancelFunc{root: cancel}
416 + q := []Context{root}
417 + // Create a tree of contexts.
418 + for len(q) != 0 && len(m) < 100 {
419 + parent := q[0]
420 + q = q[1:]
421 + for i := 0; i < 4; i++ {
422 + ctx, cancel := WithCancel(parent)
423 + m[ctx] = cancel
424 + q = append(q, ctx)
425 + }
426 + }
427 + // Start all the cancels in a random order.
428 + var wg sync.WaitGroup
429 + wg.Add(len(m))
430 + for _, cancel := range m {
431 + go func(cancel CancelFunc) {
432 + cancel()
433 + wg.Done()
434 + }(cancel)
435 + }
436 + // Wait on all the contexts in a random order.
437 + for ctx := range m {
438 + select {
439 + case <-ctx.Done():
440 + case <-time.After(1 * time.Second):
441 + buf := make([]byte, 10<<10)
442 + n := runtime.Stack(buf, true)
443 + t.Fatalf("timed out waiting for <-ctx.Done(); stacks:\n%s", buf[:n])
444 + }
445 + }
446 + // Wait for all the cancel functions to return.
447 + done := make(chan struct{})
448 + go func() {
449 + wg.Wait()
450 + close(done)
451 + }()
452 + select {
453 + case <-done:
454 + case <-time.After(1 * time.Second):
455 + buf := make([]byte, 10<<10)
456 + n := runtime.Stack(buf, true)
457 + t.Fatalf("timed out waiting for cancel functions; stacks:\n%s", buf[:n])
458 + }
459 +}
460 +
461 +func TestInterlockedCancels(t *testing.T) {
462 + parent, cancelParent := WithCancel(Background())
463 + child, cancelChild := WithCancel(parent)
464 + go func() {
465 + parent.Done()
466 + cancelChild()
467 + }()
468 + cancelParent()
469 + select {
470 + case <-child.Done():
471 + case <-time.After(1 * time.Second):
472 + buf := make([]byte, 10<<10)
473 + n := runtime.Stack(buf, true)
474 + t.Fatalf("timed out waiting for child.Done(); stacks:\n%s", buf[:n])
475 + }
476 +}
477 +
478 +func TestLayersCancel(t *testing.T) {
479 + testLayers(t, time.Now().UnixNano(), false)
480 +}
481 +
482 +func TestLayersTimeout(t *testing.T) {
483 + testLayers(t, time.Now().UnixNano(), true)
484 +}
485 +
486 +func testLayers(t *testing.T, seed int64, testTimeout bool) {
487 + rand.Seed(seed)
488 + errorf := func(format string, a ...interface{}) {
489 + t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...)
490 + }
491 + const (
492 + timeout = 200 * time.Millisecond
493 + minLayers = 30
494 + )
495 + type value int
496 + var (
497 + vals []*value
498 + cancels []CancelFunc
499 + numTimers int
500 + ctx = Background()
501 + )
502 + for i := 0; i < minLayers || numTimers == 0 || len(cancels) == 0 || len(vals) == 0; i++ {
503 + switch rand.Intn(3) {
504 + case 0:
505 + v := new(value)
506 + ctx = WithValue(ctx, v, v)
507 + vals = append(vals, v)
508 + case 1:
509 + var cancel CancelFunc
510 + ctx, cancel = WithCancel(ctx)
511 + cancels = append(cancels, cancel)
512 + case 2:
513 + var cancel CancelFunc
514 + ctx, cancel = WithTimeout(ctx, timeout)
515 + cancels = append(cancels, cancel)
516 + numTimers++
517 + }
518 + }
519 + checkValues := func(when string) {
520 + for _, key := range vals {
521 + if val := ctx.Value(key).(*value); key != val {
522 + errorf("%s: ctx.Value(%p) = %p want %p", when, key, val, key)
523 + }
524 + }
525 + }
526 + select {
527 + case <-ctx.Done():
528 + errorf("ctx should not be canceled yet")
529 + default:
530 + }
531 + if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) {
532 + t.Errorf("ctx.String() = %q want prefix %q", s, prefix)
533 + }
534 + t.Log(ctx)
535 + checkValues("before cancel")
536 + if testTimeout {
537 + select {
538 + case <-ctx.Done():
539 + case <-time.After(timeout + timeout/10):
540 + errorf("ctx should have timed out")
541 + }
542 + checkValues("after timeout")
543 + } else {
544 + cancel := cancels[rand.Intn(len(cancels))]
545 + cancel()
546 + select {
547 + case <-ctx.Done():
548 + default:
549 + errorf("ctx should be canceled")
550 + }
551 + checkValues("after cancel")
552 + }
553 +}
Godeps/_workspace/src/code.google.com/p/go.net/context/withtimeout_test.go new
+26
@@ -0,0 +1,26 @@
1 +// Copyright 2014 The Go Authors. All rights reserved.
2 +// Use of this source code is governed by a BSD-style
3 +// license that can be found in the LICENSE file.
4 +
5 +package context_test
6 +
7 +import (
8 + "fmt"
9 + "time"
10 +
11 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12 +)
13 +
14 +func ExampleWithTimeout() {
15 + // Pass a context with a timeout to tell a blocking function that it
16 + // should abandon its work after the timeout elapses.
17 + ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond)
18 + select {
19 + case <-time.After(200 * time.Millisecond):
20 + fmt.Println("overslept")
21 + case <-ctx.Done():
22 + fmt.Println(ctx.Err()) // prints "context deadline exceeded"
23 + }
24 + // Output:
25 + // context deadline exceeded
26 +}
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go
+7 -5
@@ -66,12 +66,14 @@ func bytesToString(b []byte) (ret string, err error) {
66 func addressStringToBytes(p *Protocol, s string) []byte {
67 switch p.Code {
68
69 - // ipv4,6
70 - case 4, 41:
69 + case P_IP4: // ipv4
70 return net.ParseIP(s).To4()
71
72 + case P_IP6: // ipv6
73 + return net.ParseIP(s).To16()
74 +
75 // tcp udp dccp sctp
74 - case 6, 17, 33, 132:
76 + case P_TCP, P_UDP, P_DCCP, P_SCTP:
77 b := make([]byte, 2)
78 i, err := strconv.Atoi(s)
79 if err == nil {
@@ -87,11 +89,11 @@ func addressBytesToString(p *Protocol, b []byte) string {
89 switch p.Code {
90
91 // ipv4,6
90 - case 4, 41:
92 + case P_IP4, P_IP6:
93 return net.IP(b).String()
94
95 // tcp udp dccp sctp
94 - case 6, 17, 33, 132:
96 + case P_TCP, P_UDP, P_DCCP, P_SCTP:
97 i := binary.BigEndian.Uint16(b)
98 return strconv.Itoa(int(i))
99 }
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net.go new
+77
@@ -0,0 +1,77 @@
1 +package multiaddr
2 +
3 +import (
4 + "fmt"
5 + "net"
6 +)
7 +
8 +var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion")
9 +
10 +// FromNetAddr converts a net.Addr type to a Multiaddr.
11 +func FromNetAddr(a net.Addr) (*Multiaddr, error) {
12 + switch a.Network() {
13 + case "tcp", "tcp4", "tcp6":
14 + ac, ok := a.(*net.TCPAddr)
15 + if !ok {
16 + return nil, errIncorrectNetAddr
17 + }
18 +
19 + // Get IP Addr
20 + ipm, err := FromIP(ac.IP)
21 + if err != nil {
22 + return nil, errIncorrectNetAddr
23 + }
24 +
25 + // Get TCP Addr
26 + tcpm, err := NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port))
27 + if err != nil {
28 + return nil, errIncorrectNetAddr
29 + }
30 +
31 + // Encapsulate
32 + return ipm.Encapsulate(tcpm), nil
33 +
34 + case "udp", "upd4", "udp6":
35 + ac, ok := a.(*net.UDPAddr)
36 + if !ok {
37 + return nil, errIncorrectNetAddr
38 + }
39 +
40 + // Get IP Addr
41 + ipm, err := FromIP(ac.IP)
42 + if err != nil {
43 + return nil, errIncorrectNetAddr
44 + }
45 +
46 + // Get UDP Addr
47 + udpm, err := NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port))
48 + if err != nil {
49 + return nil, errIncorrectNetAddr
50 + }
51 +
52 + // Encapsulate
53 + return ipm.Encapsulate(udpm), nil
54 +
55 + case "ip", "ip4", "ip6":
56 + ac, ok := a.(*net.IPAddr)
57 + if !ok {
58 + return nil, errIncorrectNetAddr
59 + }
60 + return FromIP(ac.IP)
61 +
62 + default:
63 + return nil, fmt.Errorf("unknown network %v", a.Network())
64 + }
65 +}
66 +
67 +// FromIP converts a net.IP type to a Multiaddr.
68 +func FromIP(ip net.IP) (*Multiaddr, error) {
69 + switch {
70 + case ip.To4() != nil:
71 + return NewMultiaddr("/ip4/" + ip.String())
72 + case ip.To16() != nil:
73 + return NewMultiaddr("/ip6/" + ip.String())
74 + default:
75 + return nil, errIncorrectNetAddr
76 + }
77 +}
Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net_test.go new
+49
@@ -0,0 +1,49 @@
1 +package multiaddr
2 +
3 +import (
4 + "net"
5 + "testing"
6 +)
7 +
8 +type GenFunc func() (*Multiaddr, error)
9 +
10 +func testConvert(t *testing.T, s string, gen GenFunc) {
11 + m, err := gen()
12 + if err != nil {
13 + t.Fatal("failed to generate.")
14 + }
15 +
16 + if s2, _ := m.String(); err != nil || s2 != s {
17 + t.Fatal("failed to convert: " + s + " != " + s2)
18 + }
19 +}
20 +
21 +func TestFromIP4(t *testing.T) {
22 + testConvert(t, "/ip4/10.20.30.40", func() (*Multiaddr, error) {
23 + return FromIP(net.ParseIP("10.20.30.40"))
24 + })
25 +}
26 +
27 +func TestFromIP6(t *testing.T) {
28 + testConvert(t, "/ip6/2001:4860:0:2001::68", func() (*Multiaddr, error) {
29 + return FromIP(net.ParseIP("2001:4860:0:2001::68"))
30 + })
31 +}
32 +
33 +func TestFromTCP(t *testing.T) {
34 + testConvert(t, "/ip4/10.20.30.40/tcp/1234", func() (*Multiaddr, error) {
35 + return FromNetAddr(&net.TCPAddr{
36 + IP: net.ParseIP("10.20.30.40"),
37 + Port: 1234,
38 + })
39 + })
40 +}
41 +
42 +func TestFromUDP(t *testing.T) {
43 + testConvert(t, "/ip4/10.20.30.40/udp/1234", func() (*Multiaddr, error) {
44 + return FromNetAddr(&net.UDPAddr{
45 + IP: net.ParseIP("10.20.30.40"),
46 + Port: 1234,
47 + })
48 + })
49 +}
core/core.go
+3 -3
@@ -77,8 +77,8 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
77 var (
78 net *swarm.Swarm
79 // TODO: refactor so we can use IpfsRouting interface instead of being DHT-specific
80 - route* dht.IpfsDHT
81 - swap *bitswap.BitSwap
80 + route *dht.IpfsDHT
81 + swap *bitswap.BitSwap
82 )
83
84 if online {
@@ -134,7 +134,7 @@ func initIdentity(cfg *config.Config) (*peer.Peer, error) {
134 return nil, err
135 }
136
137 - addresses = []*ma.Multiaddr{ maddr }
137 + addresses = []*ma.Multiaddr{maddr}
138 }
139
140 skb, err := base64.StdEncoding.DecodeString(cfg.Identity.PrivKey)
net/message/message.go
+1 -1
@@ -3,7 +3,7 @@ package message
3 import (
4 peer "github.com/jbenet/go-ipfs/peer"
5
6 - proto "code.google.com/p/goprotobuf/proto"
6 + proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
7 )
8
9 // Message represents a packet of information sent to or received from a
net/mux/mux.go
+2 -2
@@ -6,8 +6,8 @@ import (
6 msg "github.com/jbenet/go-ipfs/net/message"
7 u "github.com/jbenet/go-ipfs/util"
8
9 - context "code.google.com/p/go.net/context"
10 - proto "code.google.com/p/goprotobuf/proto"
9 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
10 + proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
11 )
12
13 // Protocol objects produce + consume raw data. They are added to the Muxer
net/mux/mux.pb.go
+1 -1
@@ -13,7 +13,7 @@ It has these top-level messages:
13 */
14 package mux
15
16 -import proto "code.google.com/p/gogoprotobuf/proto"
16 +import proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto"
17 import json "encoding/json"
18 import math "math"
19
net/mux/mux_test.go
+2 -2
@@ -9,9 +9,9 @@ import (
9 msg "github.com/jbenet/go-ipfs/net/message"
10 peer "github.com/jbenet/go-ipfs/peer"
11 u "github.com/jbenet/go-ipfs/util"
12 - mh "github.com/jbenet/go-multihash"
12 + mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
13
14 - context "code.google.com/p/go.net/context"
14 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
15 )
16
17 type TestProtocol struct {
net/service/request.go
+1 -1
@@ -6,7 +6,7 @@ import (
6 msg "github.com/jbenet/go-ipfs/net/message"
7 peer "github.com/jbenet/go-ipfs/peer"
8
9 - proto "code.google.com/p/goprotobuf/proto"
9 + proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
10 )
11
12 const (
net/service/request.pb.go
+1 -1
@@ -13,7 +13,7 @@ It has these top-level messages:
13 */
14 package service
15
16 -import proto "code.google.com/p/gogoprotobuf/proto"
16 +import proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto"
17 import json "encoding/json"
18 import math "math"
19
net/service/service.go
+1 -1
@@ -7,7 +7,7 @@ import (
7 msg "github.com/jbenet/go-ipfs/net/message"
8 u "github.com/jbenet/go-ipfs/util"
9
10 - context "code.google.com/p/go.net/context"
10 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
11 )
12
13 // Handler is an interface that objects must implement in order to handle
net/service/service_test.go
+2 -2
@@ -8,8 +8,8 @@ import (
8 msg "github.com/jbenet/go-ipfs/net/message"
9 peer "github.com/jbenet/go-ipfs/peer"
10
11 - context "code.google.com/p/go.net/context"
12 - mh "github.com/jbenet/go-multihash"
11 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12 + mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
13 )
14
15 // ReverseHandler reverses all Data it receives and sends it back.