-
Notifications
You must be signed in to change notification settings - Fork 226
feat: add method CancelWithError()
#589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I'm interested in knowing if the execution was cancelled, and I don't want to rely on string matching the error message to know it.
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR.
It is crucial that cancellation preserve the backtrace of the Starlark call stack so that the user can tell what function was interrupted by cancellation. The existing code in Call will cause the leaf error (cancellation) to be wrapped by EvalError, if it's not already an EvalError, so I think it should work correctly. But can you add a test (or modify your current test) so that a stack of calls f->g->h is cancelled while h is running (e.g. counting to infinity), and assert that the resulting error has both (a) a call stack showing f, g, h and responds to errors.Is(err, Cancelled)?
Cleaner. Plus avoid wrapping errors that were previously wrapped.
Hey @adonovan, thanks for the review. I addressed your feedback. Let me know what you think. |
starlark/eval_test.go
Outdated
` | ||
cancelErr := errors.New("nope") | ||
go func() { | ||
for !ready.Load() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not how to wait for an event; use a semaphore (sync.WaitGroup) or just a channel.
But why not just have the ready
function cancel its own Thread? The concurrency of polling is not what's being tested here. The Starlark program then reduces to:
def f(): g()
def g(): h()
def h(): cancel()
and the cancel builtin function becomes:
"cancel": starlark.NewBuiltin(...) {
thread.CancelWithError(cancelErr)
return starlark.None, nil
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see value in testing internally (sync?) and externally (async?) triggered cancellations, but I'm happy to change it.
80929a3
to
22391d3
Compare
I'm interested in knowing if the execution was cancelled, and I don't want to rely on string matching the error message to know it.