diff --git a/vlib/context/_context.v b/vlib/context/_context.v index b7f20c2705..5d4e2d1e64 100644 --- a/vlib/context/_context.v +++ b/vlib/context/_context.v @@ -1,19 +1,23 @@ +// This module defines the Context type, which carries deadlines, cancellation signals, +// and other request-scoped values across API boundaries and between processes. +// Based off: https://github.com/golang/go/tree/master/src/context +// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 module context import time -pub const ( +const ( background = EmptyContext(0) todo = EmptyContext(1) cancel_context_key = 'context.CancelContext' // canceled is the error returned by Context.err when the context is canceled. - canceled = 'context canceled' + canceled = error('context canceled') // deadline_exceeded is the error returned by Context.err when the context's // deadline passes. - deadline_exceeded = 'context deadline exceeded' + deadline_exceeded = error('context deadline exceeded') ) pub interface Context { @@ -37,7 +41,7 @@ pub interface Context { // canceled if the context was canceled // or deadline_exceeded if the context's deadline passed. // After err returns a non-nil error, successive calls to err return the same error. - err() string + err() IError // Value returns the value associated with this context for key, or nil // if no value is associated with key. Successive calls to Value with // the same key returns the same result. diff --git a/vlib/context/cancel.v b/vlib/context/cancel.v index 5d7654fc5e..f3fc3b91c2 100644 --- a/vlib/context/cancel.v +++ b/vlib/context/cancel.v @@ -1,3 +1,7 @@ +// This module defines the Context type, which carries deadlines, cancellation signals, +// and other request-scoped values across API boundaries and between processes. +// Based off: https://github.com/golang/go/tree/master/src/context +// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 module context import rand @@ -6,7 +10,7 @@ import time pub interface Canceler { id string - cancel(remove_from_parent bool, err string) + cancel(remove_from_parent bool, err IError) done() chan int } @@ -31,7 +35,7 @@ mut: mutex &sync.Mutex done chan int children map[string]Canceler - err string + err IError } // with_cancel returns a copy of parent with a new done channel. The returned @@ -52,6 +56,7 @@ fn new_cancel_context(parent Context) &CancelContext { id: rand.uuid_v4() context: parent mutex: sync.new_mutex() + done: chan int{cap: 2} } } @@ -66,7 +71,7 @@ pub fn (mut ctx CancelContext) done() chan int { return done } -pub fn (mut ctx CancelContext) err() string { +pub fn (mut ctx CancelContext) err() IError { ctx.mutex.@lock() err := ctx.err ctx.mutex.unlock() @@ -84,13 +89,13 @@ pub fn (ctx CancelContext) str() string { return context_name(ctx.context) + '.with_cancel' } -fn (mut ctx CancelContext) cancel(remove_from_parent bool, err string) { - if err == '' { +fn (mut ctx CancelContext) cancel(remove_from_parent bool, err IError) { + if err.str() == 'none' { panic('context: internal error: missing cancel error') } ctx.mutex.@lock() - if ctx.err != '' { + if ctx.err.str() != 'none' { ctx.mutex.unlock() // already canceled return @@ -141,7 +146,7 @@ fn propagate_cancel(parent Context, mut child Canceler) { return } - if p.err != '' { + if p.err.str() != 'none' { // parent has already been canceled child.cancel(false, p.err) } else { diff --git a/vlib/context/deadline.v b/vlib/context/deadline.v index f67de09f66..3fc050f1f0 100644 --- a/vlib/context/deadline.v +++ b/vlib/context/deadline.v @@ -1,3 +1,7 @@ +// This module defines the Context type, which carries deadlines, cancellation signals, +// and other request-scoped values across API boundaries and between processes. +// Based off: https://github.com/golang/go/tree/master/src/context +// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 module context import rand @@ -43,7 +47,7 @@ pub fn with_deadline(parent Context, d time.Time) Context { return Context(ctx) } - if ctx.cancel_ctx.err() == '' { + if ctx.err().str() == 'none' { go fn (mut ctx TimerContext, dur time.Duration) { time.sleep(dur) ctx.cancel(true, deadline_exceeded) @@ -68,7 +72,7 @@ pub fn (mut ctx TimerContext) done() chan int { return ctx.cancel_ctx.done() } -pub fn (mut ctx TimerContext) err() string { +pub fn (mut ctx TimerContext) err() IError { return ctx.cancel_ctx.err() } @@ -76,7 +80,7 @@ pub fn (ctx TimerContext) value(key string) ?voidptr { return ctx.cancel_ctx.value(key) } -pub fn (mut ctx TimerContext) cancel(remove_from_parent bool, err string) { +pub fn (mut ctx TimerContext) cancel(remove_from_parent bool, err IError) { ctx.cancel_ctx.cancel(false, err) if remove_from_parent { // Remove this TimerContext from its parent CancelContext's children. diff --git a/vlib/context/empty.v b/vlib/context/empty.v index 9cfb53b230..335369a9ab 100644 --- a/vlib/context/empty.v +++ b/vlib/context/empty.v @@ -1,3 +1,7 @@ +// This module defines the Context type, which carries deadlines, cancellation signals, +// and other request-scoped values across API boundaries and between processes. +// Based off: https://github.com/golang/go/tree/master/src/context +// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 module context import time @@ -18,8 +22,9 @@ pub fn (ctx EmptyContext) done() chan int { return ch } -pub fn (ctx EmptyContext) err() string { - return '' +pub fn (ctx EmptyContext) err() IError { + // TODO: Change this to `none` + return none_ } pub fn (ctx EmptyContext) value(key string) ?voidptr { diff --git a/vlib/context/err.v b/vlib/context/err.v new file mode 100644 index 0000000000..23cfe568e6 --- /dev/null +++ b/vlib/context/err.v @@ -0,0 +1,12 @@ +module context + +const none_ = IError(&None{}) + +struct None { + msg string + code int +} + +fn (_ None) str() string { + return 'none' +} diff --git a/vlib/context/value.v b/vlib/context/value.v index a5da6b575d..19a2289207 100644 --- a/vlib/context/value.v +++ b/vlib/context/value.v @@ -1,3 +1,7 @@ +// This module defines the Context type, which carries deadlines, cancellation signals, +// and other request-scoped values across API boundaries and between processes. +// Based off: https://github.com/golang/go/tree/master/src/context +// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 module context import time @@ -37,7 +41,7 @@ pub fn (ctx ValueContext) done() chan int { return ctx.context.done() } -pub fn (ctx ValueContext) err() string { +pub fn (ctx ValueContext) err() IError { return ctx.context.err() }