-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move to errext and simplify the context wrapper for test.abort()
This is required to pevent import loops, since we need to move a lot of lib/ types to execution/.
- Loading branch information
Showing
3 changed files
with
55 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package errext | ||
|
||
import ( | ||
"context" | ||
) | ||
|
||
// cancelReasonKey is the key used to store both the cancel function for the | ||
// context, and the reason it of an executor. This is a work around to avoid | ||
// excessive changes for the ability of nested functions to cancel the passed | ||
// context and provide the reason they did so. | ||
type cancelAndReasonKey struct{} | ||
|
||
type cancelAndReasonCtxVal struct { | ||
cancel context.CancelFunc | ||
reason error | ||
} | ||
|
||
// CancellableContext returns context.Context that can be cancelled by calling | ||
// CancelContextWithError. It is used to initialize contexts that will be passed | ||
// to executors. | ||
// | ||
// This allows executors to globally halt any executions that uses this context. | ||
// Example use case is when a script calls test.abort(). | ||
// | ||
// TODO: maybe make this into a custom type on top of context.Context? A | ||
// k6-specific interface that has an extra method to cancel it with a reason? | ||
func CancellableContext(ctx context.Context) (context.Context, func() error) { | ||
ctx, cancel := context.WithCancel(ctx) | ||
val := &cancelAndReasonCtxVal{cancel: cancel} | ||
reasonGetter := func() error { | ||
return val.reason | ||
} | ||
return context.WithValue(ctx, cancelAndReasonKey{}, val), reasonGetter | ||
} | ||
|
||
// CancelContextWithError cancels the executor context found in ctx and saves | ||
// the given error inside. | ||
// | ||
// ctx can only be a context created by the execution.Scheduler and passed to an | ||
// executor's Run() method, this function will panic for any other context | ||
func CancelContextWithError(ctx context.Context, err error) { | ||
x := ctx.Value(cancelAndReasonKey{}) | ||
if x == nil { | ||
panic("invalid context value, not cancellable") | ||
} | ||
v, ok := x.(*cancelAndReasonCtxVal) | ||
if !ok { | ||
panic("invalid context value, missing cancel reason and function") | ||
} | ||
v.reason = err | ||
v.cancel() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters