Documentation
¶
Overview ¶
Package contextx provides extended functionality to the context package.
Index ¶
- Variables
- func Anyways(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc)
- func CancelRead(reader io.Reader) error
- func CancelWrite(writer io.Writer) error
- func Canceled() context.Context
- func Copy(ctx context.Context, dst io.Writer, src io.Reader) (written int64, err error)
- func Run[T any](ctx context.Context, f func(start func()) T, cancel func()) (t T, err error)
- func Run2[T1, T2 any](ctx context.Context, f func(start func()) (T1, T2), cancel func()) (t1 T1, t2 T2, err error)
- func WithValues(parent context.Context, values map[any]any) context.Context
- func WithValuesOf(parent, values context.Context) context.Context
Examples ¶
Constants ¶
This section is empty.
Variables ¶
ErrCanceled is the cancel cause returned by Canceled.
Functions ¶
func Anyways ¶
Anyways behaves similar to context.WithTimeout. However if the context is already cancelled before Anyways is called, the returned context's Done() channel is only closed after timeout.
Example ¶
const short = 100 * time.Millisecond // on a non-cancelled context it just behaves like short { ctx, cancel := Anyways(context.Background(), short) defer cancel() start := time.Now() <-ctx.Done() waited := time.Since(start) > short fmt.Println("Background() waited more than short:", waited) } // on a canceled context it delays the cancellation by the timeout { ctx, cancel := Anyways(Canceled(), short) defer cancel() start := time.Now() <-ctx.Done() waited := time.Since(start) > short fmt.Println("Canceled() waited more than short:", waited) }
Output: Background() waited more than short: true Canceled() waited more than short: true
func CancelRead ¶
CancelRead attempts to cancel any in-progress and future reads on the given reader. In particular, this function sets the read deadline to the current time and closes the reader.
func CancelWrite ¶
CancelWrite attempts to cancel any in-progress and future writes on the given writer. In particular, this function sets the write deadline to the current time and closes the writer.
func Canceled ¶
Canceled returns a non-nil, empty Context. It has no deadline, has no values, and is already canceled. The cancel cause is ErrCanceled.
Canceled may or may not return the same context for different invocations.
Example ¶
ctx := Canceled() select { case <-ctx.Done(): fmt.Println("context was canceled") default: fmt.Println("context was not canceled") }
Output: context was canceled
func Copy ¶
Copy copies from src to dst, stopping once ctx is closed. See io.Copy() for a description of the copy behavior.
The operation is cancelled by closing the src and destination (if they support the Close() interface). Futhermore appropriate read and write deadlines are set. Either of these calls may not have any effect, depending on the underlying operation.
func Run ¶
Run adds context-like functionality to a function that only supports explicit cancellation functionality.
In principle, it calls f and returns the provided returns f(), nil. If the context is cancelled before f returns, Run instead invokes cancel and returns f(), ctx.Err().
f can control at which point cancellation may occur. It must call start as soon as cancel may be called.
Calling start multiple times or not at all is also permitted. However these use-cases should be carefully considered. In cases where start is not called, cancel will never be called, regardless of when ctx is cancelled. In cases where start is called multiple times, cancel may be invoked immediately after the first invocation.
Run always waits for f to return, and always returns the return value of f as the first argument, even if cancel is called.
Example ¶
// for this example, we create a "work" function that runs until the cancel function is called. var work func() int var cancel func() { done := make(chan struct{}) work = func() int { fmt.Println("start working") <-done fmt.Println("done working") return 42 } cancel = func() { fmt.Println("cancel called") close(done) } } // create a context that is stopped after 100 milliseconds ctx, ctxCancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer ctxCancel() // and run the function with the context and explicit cancel! result, err := Run(ctx, func(start func()) int { start() // allow calling cancel immediately! // start the work! return work() }, cancel) fmt.Println(result, err)
Output: start working cancel called done working 42 context deadline exceeded
func Run2 ¶
func Run2[T1, T2 any](ctx context.Context, f func(start func()) (T1, T2), cancel func()) (t1 T1, t2 T2, err error)
Run2 behaves exactly like Run, except that it allows f to return two values.
func WithValues ¶
WithValues creates a new context that inherits from parent, but has associated values from values.
This function is equivalent to repeated invocations of context.WithValue. See the appropriate documentation for details on restrictions of keys and values to be used.
Example ¶
// create a background context without any values original := context.Background() // add two values to it! derived := WithValues(original, map[any]any{ oneContextKey: "hello earth", twoContextKey: "hello mars", }) // we just set these above fmt.Println(derived.Value(oneContextKey)) fmt.Println(derived.Value(twoContextKey)) // this context key has nothing associated with it fmt.Println(derived.Value(threeContextKey))
Output: hello earth hello mars <nil>
func WithValuesOf ¶
WithValuesOf creates a new context that inherits from parent, but values stored in values take precedence over already associated values. If a value is not found in values, the parent context is searched. For explicitly associating a specific map of values see WithValues.
Example ¶
// create a primary context with 'hello' values. // Note that we only fill '1' and '2' here. primary := WithValues(context.Background(), map[any]any{ oneContextKey: "hello earth", twoContextKey: "hello mars", }) // create a secondary context with 'bye' values // note that we only fill '2' and '3' here. secondary := WithValues(context.Background(), map[any]any{ twoContextKey: "bye mars", threeContextKey: "bye venus", }) // now creates a derived context that overrides the values of primary with secondary. derived := WithValuesOf(primary, secondary) // found only in primary fmt.Println(derived.Value(oneContextKey)) // found in both, the secondary overrides fmt.Println(derived.Value(twoContextKey)) // found only in secondary fmt.Println(derived.Value(threeContextKey)) // found in neither fmt.Println(derived.Value(fourContextKey))
Output: hello earth bye mars bye venus <nil>
Types ¶
This section is empty.