diff --git a/vlib/context/README.md b/vlib/context/README.md index 193badc409..ce3e8ce0c5 100644 --- a/vlib/context/README.md +++ b/vlib/context/README.md @@ -60,8 +60,7 @@ fn example_with_cancel() { } mut background := context.background() - mut b := &background - mut ctx, cancel := context.with_cancel(mut b) + mut ctx, cancel := context.with_cancel(mut &background) defer { cancel() } @@ -92,8 +91,7 @@ const ( fn example_with_deadline() { dur := time.now().add(short_duration) mut background := context.background() - mut b := &background - mut ctx, cancel := context.with_deadline(mut b, dur) + mut ctx, cancel := context.with_deadline(mut &background, dur) defer { // Even though ctx will be expired, it is good practice to call its @@ -129,8 +127,7 @@ fn example_with_timeout() { // Pass a context with a timeout to tell a blocking function that it // should abandon its work after the timeout elapses. mut background := context.background() - mut b := &background - mut ctx, cancel := context.with_timeout(mut b, short_duration) + mut ctx, cancel := context.with_timeout(mut &background, short_duration) defer { cancel() } diff --git a/vlib/context/_context.v b/vlib/context/_context.v deleted file mode 100644 index 8750fcc348..0000000000 --- a/vlib/context/_context.v +++ /dev/null @@ -1,100 +0,0 @@ -// This module defines the Context type, which carries deadlines, cancellation signals, -// and other request-scoped values across API boundaries and between processes. -// Based on: https://github.com/golang/go/tree/master/src/context -// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 -module context - -import time - -const ( - background = EmptyContext(0) - todo = EmptyContext(1) - - cancel_context_key = Key('context.CancelContext') - - // canceled is the error returned by Context.err when the context is canceled. - canceled = error('context canceled') - - // deadline_exceeded is the error returned by Context.err when the context's - // deadline passes. - deadline_exceeded = error('context deadline exceeded') -) - -// Key represents the type for the ValueContext key -pub type Key = bool - | byte - | f32 - | f64 - | i16 - | i64 - | i8 - | int - | string - | u16 - | u32 - | u64 - | voidptr - -// Any represents a generic type for the ValueContext -pub interface Any {} - -pub interface Context { - // deadline returns the time when work done on behalf of this context - // should be canceled. deadline returns none when no deadline is - // set. Successive calls to deadline return the same results. - deadline() ?time.Time - // 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. - // - // Use context values only for request-scoped data that transits - // processes and API boundaries, not for passing optional parameters to - // functions. - // - // A key identifies a specific value in a Context. Functions that wish - // to store values in Context typically allocate a key in a global - // variable then use that key as the argument to context.with_value and - // Context.Value. A key can be any type that supports equality; - // packages should define keys as an unexported type to avoid - // collisions. - value(key Key) ?Any - str() string - // done returns a channel that's closed when work done on behalf of this - // context should be canceled. done may return nil if this context can - // never be canceled. Successive calls to done return the same value. - // The close of the done channel may happen asynchronously, - // after the cancel function returns. - // - // with_cancel arranges for done to be closed when cancel is called; - // with_deadline arranges for done to be closed when the deadline - // expires; with_timeout arranges for done to be closed when the timeout - // elapses. -mut: - done() chan int - // If done is not yet closed, err returns nil. - // If done is closed, err returns a non-nil error explaining why: - // 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() IError -} - -// background returns an empty Context. It is never canceled, has no -// values, and has no deadline. It is typically used by the main function, -// initialization, and tests, and as the top-level Context for incoming -// requests. -pub fn background() Context { - return context.background -} - -// todo returns an empty Context. Code should use todo when -// it's unclear which Context to use or it is not yet available (because the -// surrounding function has not yet been extended to accept a Context -// parameter). -pub fn todo() Context { - return context.todo -} - -fn context_name(ctx Context) string { - return typeof(ctx) -} diff --git a/vlib/context/cancel_test.v b/vlib/context/cancel_test.v index 6e9baad72c..cd5033c347 100644 --- a/vlib/context/cancel_test.v +++ b/vlib/context/cancel_test.v @@ -31,8 +31,7 @@ fn test_with_cancel() { } mut background := context.background() - mut b := &background - mut ctx, cancel := context.with_cancel(mut b) + mut ctx, cancel := context.with_cancel(mut &background) defer { cancel() } diff --git a/vlib/context/context.v b/vlib/context/context.v new file mode 100644 index 0000000000..7eff04915d --- /dev/null +++ b/vlib/context/context.v @@ -0,0 +1,107 @@ +// This module defines the Context type, which carries deadlines, cancellation signals, +// and other request-scoped values across API boundaries and between processes. +// Based on: https://github.com/golang/go/tree/master/src/context +// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 +module context + +import time + +const ( + background = EmptyContext(0) + todo = EmptyContext(1) + + cancel_context_key = Key('context.CancelContext') + + // canceled is the error returned by Context.err when the context is canceled. + canceled = error('context canceled') + + // deadline_exceeded is the error returned by Context.err when the context's + // deadline passes. + deadline_exceeded = error('context deadline exceeded') +) + +// Key represents the type for the ValueContext key +pub type Key = bool + | byte + | f32 + | f64 + | i16 + | i64 + | i8 + | int + | string + | u16 + | u32 + | u64 + | voidptr + +// Any represents a generic type for the ValueContext +pub interface Any {} + +// `Context` is an interface that defined the minimum required functionality +// for a Context. +// +// `deadline()` returns the time when work done on behalf of this context +// should be canceled. deadline returns none when no deadline is +// set. Successive calls to deadline return the same results. +// +// `value(key)` returns an Optional that wraps the value associated with this context for key. +// It returns none if no value is associated with key. Successive calls to Value with +// the same key returns the same result. +// +// Use context values only for request-scoped data that transits +// processes and API boundaries, not for passing optional parameters to +// functions. +// +// A key identifies a specific value in a Context. Functions that wish +// to store values in Context typically allocate a key in a global +// variable then use that key as the argument to context.with_value and +// Context.value. A key can be any type that supports equality; +// modules should define keys as an unexported type to avoid +// collisions. +// +// `done()` returns a channel that's closed when work done on behalf of this +// context should be canceled. done may return a closed channel if this context can +// never be canceled. Successive calls to done return the same value. +// The close of the done channel may happen asynchronously, +// after the cancel function returns. +// +// with_cancel arranges for done to be closed when cancel is called; +// with_deadline arranges for done to be closed when the deadline +// expires; with_timeout arranges for done to be closed when the timeout +// elapses. +// +// `err()` returns an IError based on some conditions +// If done is not yet closed, err returns none. +// If done is closed, err returns a non-none error explaining why: +// canceled if the context was canceled +// or deadline_exceeded if the context's deadline passed. +// After err returns a non-none error, successive calls to err return the same error. +pub interface Context { + deadline() ?time.Time + value(key Key) ?Any + str() string +mut: + done() chan int + err() IError +} + +// background returns an empty Context. It is never canceled, has no +// values, and has no deadline. It is typically used by the main function, +// initialization, and tests, and as the top-level Context for incoming +// requests. +pub fn background() Context { + return context.background +} + +// todo returns an empty Context. Code should use todo when +// it's unclear which Context to use or it is not yet available (because the +// surrounding function has not yet been extended to accept a Context +// parameter). +pub fn todo() Context { + return context.todo +} + +fn context_name(ctx Context) string { + return typeof(ctx) +} diff --git a/vlib/context/deadline_test.v b/vlib/context/deadline_test.v index 2763c1cb80..d983c998bc 100644 --- a/vlib/context/deadline_test.v +++ b/vlib/context/deadline_test.v @@ -11,8 +11,7 @@ const ( fn test_with_deadline() { dur := time.now().add(short_duration) mut background := context.background() - mut b := &background - mut ctx, cancel := context.with_deadline(mut b, dur) + mut ctx, cancel := context.with_deadline(mut &background, dur) defer { // Even though ctx will be expired, it is good practice to call its @@ -36,8 +35,7 @@ fn test_with_timeout() { // Pass a context with a timeout to tell a blocking function that it // should abandon its work after the timeout elapses. mut background := context.background() - mut b := &background - mut ctx, cancel := context.with_timeout(mut b, short_duration) + mut ctx, cancel := context.with_timeout(mut &background, short_duration) defer { cancel() }