-
Notifications
You must be signed in to change notification settings - Fork 140
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
Implement "opinionated cancellation" #265
Implement "opinionated cancellation" #265
Conversation
rust-analyzer companion PR: rust-lang/rust-analyzer#8866 |
src/lib.rs
Outdated
} | ||
} | ||
|
||
impl std::error::Error for Canceled {} |
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 think we should have this, but this was not obvious to me, so let me write down justification.
I would expect Cancellation to not be treated as an error. Cancellation is a serendipitous success. It would be wrong to propagate Cancelled as Error. However, in salsa itself Cancelled
is not used throughout the API, as we use unwinding, its used only at the boundady. For boundaries, I think treating it as an Error is probably fine
Apparently, one L is the American variant, and I think Rust in general
favors US speling, so we should do that.
…On Mon, 17 May 2021 at 21:51, Laurențiu Nicola ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/lib.rs
<#265 (comment)>:
> @@ -644,6 +645,40 @@ where
}
}
+/// A panic payload indicating that a salsa revision was canceled.
+#[derive(Debug)]
+pub struct Canceled {
Nit: maybe call this Cancelled to match the test filename?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#265 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AANB3MY3UFTK4CHM6EQNCDDTOFQUXANCNFSM45A3BNEA>
.
|
Yeah, but there's also the more American "cancelation" which matches "canceled", while the code used "cancellation". TBH, the American spelling hurts my eyes 😅. |
src/runtime.rs
Outdated
@@ -38,6 +41,8 @@ pub struct Runtime { | |||
|
|||
/// Shared state that is accessible via all runtimes. | |||
shared_state: Arc<SharedState>, | |||
|
|||
on_cancelation_check: Option<Box<dyn Fn() + RefUnwindSafe + Send>>, |
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.
Hm, why do we need this? I imagined this can work the same way as other events, by user overriding on_salsa_event
or some such.
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.
Lines 67 to 73 in b3cb3c4
/// This function is invoked at key points in the salsa | |
/// runtime. It permits the database to be customized and to | |
/// inject logging or other custom behavior. | |
fn salsa_event(&self, event_fn: Event) { | |
#![allow(unused_variables)] | |
} | |
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.
That needs a Database
, which unwind_if_canceled
doesn't have. Should we pass the db as an argument here?
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.
Hm, perhaps we should make unwind_if_canceled
a method of the Database
then? That would actually give a nice way to opt-out of unwinding -- overrride it to be no-op. Not sure if I love or hate that flexibility though.
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 looks basically good to me -- I wasn't clear @jonas-schievink on whether there are broken tests? I guess I can check CI :
src/runtime.rs
Outdated
assert_eq!(pending_revision, current_revision); | ||
self.report_anon_read(pending_revision); | ||
false | ||
self.unwind_canceled(); |
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 simplification is quite nice.
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'm a bit worried that there could be a subtle bug if we allowed users to override cancelation here.
src/runtime.rs
Outdated
|
||
/// Registers a callback to be invoked every time [`Runtime::unwind_if_canceled`] is called | ||
/// (either automatically by salsa, or manually by user code). | ||
pub fn set_cancelation_check_callback<F>(&mut self, callback: F) |
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 don't know why, but "cancellation" is far more common...
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 agree with @matklad that it would be nice to do this via salsa_event
-- do we have a concrete use for this?
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.
The primary use case is to assert that no more than N milliseconds pass between cancellation checks, which is helpful for debugging long-running queries that affect rust-analyzer responsiveness
can you try running the tests with |
Test failure backtrace:
|
@jonas-schievink hmm that's not very useful. I was hoping for a backtrace more in the spawned threads. I'll try to run myself. |
OK, so the error seeems-- ah, I know what's going on. Maybe it was obvious to you, @jonas-schievink, but it wasn't to me. What is happening is that the call to |
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 looks great!
src/lib.rs
Outdated
/// Cancellation will automatically be triggered by salsa on any query | ||
/// invocation. | ||
/// | ||
/// This method should not be overridden by `Database` implementors. |
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.
We should mention that it invokes salsa_event
with WillCheckCancellation
, so implementors can override that to intercept.
Oh, I guess I should have marked that as "Request changes". Apart from the documentation nit, r=me |
bors r=nikomatsakis |
Build succeeded: |
- new cancellation API salsa-rs#265
8866: Update salsa r=matklad a=jonas-schievink This updates salsa to include salsa-rs/salsa#265, and removes all cancellation-related code from rust-analyzer Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This implements the design described in RFC #262.
Currently, the
in_par_get_set_cancellation
test is failing. I'm not completely sure what it is trying to test (the comment on the test does not match its behavior), so I couldn't fix it.