v / vlib / context / context.v
106 lines · 97 sloc · 3.64 KB · 56e02481a4f0e421009413f58493620cc3a51f87
Raw
1// This module defines the Context type, which carries deadlines, cancellation signals,
2// and other request-scoped values across API boundaries and between processes.
3// Based on: https://github.com/golang/go/tree/master/src/context
4// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2
5module context
6
7import time
8
9const cancel_context_key = Key('context.CancelContext')
10
11// canceled is the error returned by Context.err when the context is canceled.
12const canceled = error('context canceled')
13
14// deadline_exceeded is the error returned by Context.err when the context's
15// deadline passes.
16const deadline_exceeded = error('context deadline exceeded')
17
18// Key represents the type for the ValueContext key
19pub type Key = bool | f32 | f64 | i16 | i64 | i8 | int | string | u16 | u32 | u64 | u8 | voidptr
20
21// Any represents a generic type for the ValueContext
22pub interface Any {}
23
24// `Context` is an interface that defined the minimum required functionality
25// for a Context.
26//
27// `deadline()` returns the time when work done on behalf of this context
28// should be canceled. deadline returns none when no deadline is
29// set. Successive calls to deadline return the same results.
30//
31// `value(key)` returns an Optional that wraps the value associated with this context for key.
32// It returns none if no value is associated with key. Successive calls to Value with
33// the same key returns the same result.
34//
35// Use context values only for request-scoped data that transits
36// processes and API boundaries, not for passing optional parameters to
37// functions.
38//
39// A key identifies a specific value in a Context. Functions that wish
40// to store values in Context typically allocate a key in a global
41// variable then use that key as the argument to context.with_value and
42// Context.value. A key can be any type that supports equality;
43// modules should define keys as an unexported type to avoid
44// collisions.
45//
46// `done()` returns a channel that's closed when work done on behalf of this
47// context should be canceled. done may return a closed channel if this context can
48// never be canceled. Successive calls to done return the same value.
49// The close of the done channel may happen asynchronously,
50// after the cancel function returns.
51//
52// with_cancel arranges for done to be closed when cancel is called;
53// with_deadline arranges for done to be closed when the deadline
54// expires; with_timeout arranges for done to be closed when the timeout
55// elapses.
56//
57// `err()` returns an IError based on some conditions
58// If done is not yet closed, err returns none.
59// If done is closed, err returns a non-none error explaining why:
60// canceled if the context was canceled
61// or deadline_exceeded if the context's deadline passed.
62// After err returns a non-none error, successive calls to err return the same error.
63pub interface Context {
64 deadline() ?time.Time
65 value(key Key) ?Any
66mut:
67 done() chan int
68 err() IError
69}
70
71// str returns the `str` method of the corresponding Context struct
72pub fn (ctx &Context) str() string {
73 // since `Context` is an interface we have to manually match every possible
74 // type that implements `Context` if we want to use a `Context` as a field in a struct
75 // since the `Context` interface has to implement its own `str` method.
76 match ctx {
77 BackgroundContext {
78 return ctx.str()
79 }
80 EmptyContext {
81 return ctx.str()
82 }
83 TodoContext {
84 return ctx.str()
85 }
86 CancelContext {
87 return ctx.str()
88 }
89 CauseContext {
90 return ctx.str()
91 }
92 TimerContext {
93 return ctx.str()
94 }
95 ValueContext {
96 return ctx.str()
97 }
98 else {
99 return context_name(ctx)
100 }
101 }
102}
103
104fn context_name(ctx Context) string {
105 return typeof(ctx)
106}
107