ducky/devices

Paddy 2015-11-12

0:b6494e1a499e Go to Latest

ducky/devices/vendor/golang.org/x/net/context/context.go

Initial attempt. Create the basic types (Device, DeviceType, DeviceChange) that we'll be using in the service. Also, create our Storer interface, and the helper methods to store, retrieve, and update information in the datastore. Also, we're using Godep, so check in our Godeps folder and the vendor folder. Note that this only works on Go 1.5 and later, with the GO15VENDOREXPERIMENT environment variable set to 1.

History
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.
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
39 import (
40 "errors"
41 "fmt"
42 "sync"
43 "time"
44 )
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)
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 // // Stream generates values with DoSomething and sends them to out
68 // // until DoSomething returns an error or ctx.Done is closed.
69 // func Stream(ctx context.Context, out <-chan Value) error {
70 // for {
71 // v, err := DoSomething(ctx)
72 // if err != nil {
73 // return err
74 // }
75 // select {
76 // case <-ctx.Done():
77 // return ctx.Err()
78 // case out <- v:
79 // }
80 // }
81 // }
82 //
83 // See http://blog.golang.org/pipelines for more examples of how to use
84 // a Done channel for cancelation.
85 Done() <-chan struct{}
87 // Err returns a non-nil error value after Done is closed. Err returns
88 // Canceled if the context was canceled or DeadlineExceeded if the
89 // context's deadline passed. No other values for Err are defined.
90 // After Done is closed, successive calls to Err return the same value.
91 Err() error
93 // Value returns the value associated with this context for key, or nil
94 // if no value is associated with key. Successive calls to Value with
95 // the same key returns the same result.
96 //
97 // Use context values only for request-scoped data that transits
98 // processes and API boundaries, not for passing optional parameters to
99 // functions.
100 //
101 // A key identifies a specific value in a Context. Functions that wish
102 // to store values in Context typically allocate a key in a global
103 // variable then use that key as the argument to context.WithValue and
104 // Context.Value. A key can be any type that supports equality;
105 // packages should define keys as an unexported type to avoid
106 // collisions.
107 //
108 // Packages that define a Context key should provide type-safe accessors
109 // for the values stores using that key:
110 //
111 // // Package user defines a User type that's stored in Contexts.
112 // package user
113 //
114 // import "golang.org/x/net/context"
115 //
116 // // User is the type of value stored in the Contexts.
117 // type User struct {...}
118 //
119 // // key is an unexported type for keys defined in this package.
120 // // This prevents collisions with keys defined in other packages.
121 // type key int
122 //
123 // // userKey is the key for user.User values in Contexts. It is
124 // // unexported; clients use user.NewContext and user.FromContext
125 // // instead of using this key directly.
126 // var userKey key = 0
127 //
128 // // NewContext returns a new Context that carries value u.
129 // func NewContext(ctx context.Context, u *User) context.Context {
130 // return context.WithValue(ctx, userKey, u)
131 // }
132 //
133 // // FromContext returns the User value stored in ctx, if any.
134 // func FromContext(ctx context.Context) (*User, bool) {
135 // u, ok := ctx.Value(userKey).(*User)
136 // return u, ok
137 // }
138 Value(key interface{}) interface{}
139 }
141 // Canceled is the error returned by Context.Err when the context is canceled.
142 var Canceled = errors.New("context canceled")
144 // DeadlineExceeded is the error returned by Context.Err when the context's
145 // deadline passes.
146 var DeadlineExceeded = errors.New("context deadline exceeded")
148 // An emptyCtx is never canceled, has no values, and has no deadline. It is not
149 // struct{}, since vars of this type must have distinct addresses.
150 type emptyCtx int
152 func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
153 return
154 }
156 func (*emptyCtx) Done() <-chan struct{} {
157 return nil
158 }
160 func (*emptyCtx) Err() error {
161 return nil
162 }
164 func (*emptyCtx) Value(key interface{}) interface{} {
165 return nil
166 }
168 func (e *emptyCtx) String() string {
169 switch e {
170 case background:
171 return "context.Background"
172 case todo:
173 return "context.TODO"
174 }
175 return "unknown empty Context"
176 }
178 var (
179 background = new(emptyCtx)
180 todo = new(emptyCtx)
181 )
183 // Background returns a non-nil, empty Context. It is never canceled, has no
184 // values, and has no deadline. It is typically used by the main function,
185 // initialization, and tests, and as the top-level Context for incoming
186 // requests.
187 func Background() Context {
188 return background
189 }
191 // TODO returns a non-nil, empty Context. Code should use context.TODO when
192 // it's unclear which Context to use or it's is not yet available (because the
193 // surrounding function has not yet been extended to accept a Context
194 // parameter). TODO is recognized by static analysis tools that determine
195 // whether Contexts are propagated correctly in a program.
196 func TODO() Context {
197 return todo
198 }
200 // A CancelFunc tells an operation to abandon its work.
201 // A CancelFunc does not wait for the work to stop.
202 // After the first call, subsequent calls to a CancelFunc do nothing.
203 type CancelFunc func()
205 // WithCancel returns a copy of parent with a new Done channel. The returned
206 // context's Done channel is closed when the returned cancel function is called
207 // or when the parent context's Done channel is closed, whichever happens first.
208 //
209 // Canceling this context releases resources associated with it, so code should
210 // call cancel as soon as the operations running in this Context complete.
211 func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
212 c := newCancelCtx(parent)
213 propagateCancel(parent, &c)
214 return &c, func() { c.cancel(true, Canceled) }
215 }
217 // newCancelCtx returns an initialized cancelCtx.
218 func newCancelCtx(parent Context) cancelCtx {
219 return cancelCtx{
220 Context: parent,
221 done: make(chan struct{}),
222 }
223 }
225 // propagateCancel arranges for child to be canceled when parent is.
226 func propagateCancel(parent Context, child canceler) {
227 if parent.Done() == nil {
228 return // parent is never canceled
229 }
230 if p, ok := parentCancelCtx(parent); ok {
231 p.mu.Lock()
232 if p.err != nil {
233 // parent has already been canceled
234 child.cancel(false, p.err)
235 } else {
236 if p.children == nil {
237 p.children = make(map[canceler]bool)
238 }
239 p.children[child] = true
240 }
241 p.mu.Unlock()
242 } else {
243 go func() {
244 select {
245 case <-parent.Done():
246 child.cancel(false, parent.Err())
247 case <-child.Done():
248 }
249 }()
250 }
251 }
253 // parentCancelCtx follows a chain of parent references until it finds a
254 // *cancelCtx. This function understands how each of the concrete types in this
255 // package represents its parent.
256 func parentCancelCtx(parent Context) (*cancelCtx, bool) {
257 for {
258 switch c := parent.(type) {
259 case *cancelCtx:
260 return c, true
261 case *timerCtx:
262 return &c.cancelCtx, true
263 case *valueCtx:
264 parent = c.Context
265 default:
266 return nil, false
267 }
268 }
269 }
271 // removeChild removes a context from its parent.
272 func removeChild(parent Context, child canceler) {
273 p, ok := parentCancelCtx(parent)
274 if !ok {
275 return
276 }
277 p.mu.Lock()
278 if p.children != nil {
279 delete(p.children, child)
280 }
281 p.mu.Unlock()
282 }
284 // A canceler is a context type that can be canceled directly. The
285 // implementations are *cancelCtx and *timerCtx.
286 type canceler interface {
287 cancel(removeFromParent bool, err error)
288 Done() <-chan struct{}
289 }
291 // A cancelCtx can be canceled. When canceled, it also cancels any children
292 // that implement canceler.
293 type cancelCtx struct {
294 Context
296 done chan struct{} // closed by the first cancel call.
298 mu sync.Mutex
299 children map[canceler]bool // set to nil by the first cancel call
300 err error // set to non-nil by the first cancel call
301 }
303 func (c *cancelCtx) Done() <-chan struct{} {
304 return c.done
305 }
307 func (c *cancelCtx) Err() error {
308 c.mu.Lock()
309 defer c.mu.Unlock()
310 return c.err
311 }
313 func (c *cancelCtx) String() string {
314 return fmt.Sprintf("%v.WithCancel", c.Context)
315 }
317 // cancel closes c.done, cancels each of c's children, and, if
318 // removeFromParent is true, removes c from its parent's children.
319 func (c *cancelCtx) cancel(removeFromParent bool, err error) {
320 if err == nil {
321 panic("context: internal error: missing cancel error")
322 }
323 c.mu.Lock()
324 if c.err != nil {
325 c.mu.Unlock()
326 return // already canceled
327 }
328 c.err = err
329 close(c.done)
330 for child := range c.children {
331 // NOTE: acquiring the child's lock while holding parent's lock.
332 child.cancel(false, err)
333 }
334 c.children = nil
335 c.mu.Unlock()
337 if removeFromParent {
338 removeChild(c.Context, c)
339 }
340 }
342 // WithDeadline returns a copy of the parent context with the deadline adjusted
343 // to be no later than d. If the parent's deadline is already earlier than d,
344 // WithDeadline(parent, d) is semantically equivalent to parent. The returned
345 // context's Done channel is closed when the deadline expires, when the returned
346 // cancel function is called, or when the parent context's Done channel is
347 // closed, whichever happens first.
348 //
349 // Canceling this context releases resources associated with it, so code should
350 // call cancel as soon as the operations running in this Context complete.
351 func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
352 if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
353 // The current deadline is already sooner than the new one.
354 return WithCancel(parent)
355 }
356 c := &timerCtx{
357 cancelCtx: newCancelCtx(parent),
358 deadline: deadline,
359 }
360 propagateCancel(parent, c)
361 d := deadline.Sub(time.Now())
362 if d <= 0 {
363 c.cancel(true, DeadlineExceeded) // deadline has already passed
364 return c, func() { c.cancel(true, Canceled) }
365 }
366 c.mu.Lock()
367 defer c.mu.Unlock()
368 if c.err == nil {
369 c.timer = time.AfterFunc(d, func() {
370 c.cancel(true, DeadlineExceeded)
371 })
372 }
373 return c, func() { c.cancel(true, Canceled) }
374 }
376 // A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
377 // implement Done and Err. It implements cancel by stopping its timer then
378 // delegating to cancelCtx.cancel.
379 type timerCtx struct {
380 cancelCtx
381 timer *time.Timer // Under cancelCtx.mu.
383 deadline time.Time
384 }
386 func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
387 return c.deadline, true
388 }
390 func (c *timerCtx) String() string {
391 return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
392 }
394 func (c *timerCtx) cancel(removeFromParent bool, err error) {
395 c.cancelCtx.cancel(false, err)
396 if removeFromParent {
397 // Remove this timerCtx from its parent cancelCtx's children.
398 removeChild(c.cancelCtx.Context, c)
399 }
400 c.mu.Lock()
401 if c.timer != nil {
402 c.timer.Stop()
403 c.timer = nil
404 }
405 c.mu.Unlock()
406 }
408 // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
409 //
410 // Canceling this context releases resources associated with it, so code should
411 // call cancel as soon as the operations running in this Context complete:
412 //
413 // func slowOperationWithTimeout(ctx context.Context) (Result, error) {
414 // ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
415 // defer cancel() // releases resources if slowOperation completes before timeout elapses
416 // return slowOperation(ctx)
417 // }
418 func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
419 return WithDeadline(parent, time.Now().Add(timeout))
420 }
422 // WithValue returns a copy of parent in which the value associated with key is
423 // val.
424 //
425 // Use context Values only for request-scoped data that transits processes and
426 // APIs, not for passing optional parameters to functions.
427 func WithValue(parent Context, key interface{}, val interface{}) Context {
428 return &valueCtx{parent, key, val}
429 }
431 // A valueCtx carries a key-value pair. It implements Value for that key and
432 // delegates all other calls to the embedded Context.
433 type valueCtx struct {
434 Context
435 key, val interface{}
436 }
438 func (c *valueCtx) String() string {
439 return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
440 }
442 func (c *valueCtx) Value(key interface{}) interface{} {
443 if c.key == key {
444 return c.val
445 }
446 return c.Context.Value(key)
447 }