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
Remove a few parking_lot dependencies for faster builds #969
Conversation
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.
Has the std::sync::RwLock
cought up to the speed and safety of parking_lot
now? My understanding was that parking_lot
is quite a bit faster at runtime and has certain checks (as in for deadlocks) that it can even do at compile time. (Honestly, I have never checked that myself, I was only told that). I am not convinced I want to trade in the compile time improvement over loosing the ability to check for deadlocks at compile time.
Either way, even if we decide to go this way, please let's refrain from doing unwrap()
in any non-example non-test-code but always use expect(MSG)
(ideally with a unique MSG) instead, stating the specific assumptions that are made why this should never fail. Reason being that these assumption might be broken by later changes, and if all you get is an unwrap
-panic it is hard to figure out where that is (in particular in FFI) and why that breaks. A unique message explaining the underlying assumption is easier to find in the source code and understand why you might have violated that with your changes now.
Codecov Report
@@ Coverage Diff @@
## main #969 +/- ##
=======================================
Coverage 80.35% 80.35%
=======================================
Files 110 110
Lines 15809 15809
=======================================
Hits 12704 12704
Misses 3105 3105 Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
Yes: https://blog.rust-lang.org/2022/06/30/Rust-1.62.0.html#thinner-faster-mutexes-on-linux
There's no extra compile-time guarantees AFAIK, the docs mention a few differences of which the most important one is probably that
I disagree for this case, using |
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.
Do you think using some expect(msg)
instead of all those unwrap
would help the user to diagnostic the error faster?
No, because there is no useful detail we can add. |
Fair enough on replacing
Yes, totally agreed. But that's not what I asked for (nor the In the current code base we are even holding a lock around callback we do outside of our own codebase into the external environment (the delegates), which means the thread failure might not even be in our side of what is called, leaving a poisened lock.
Within a pure-rust environment I can accept the argument that the stack trace will tell you enough - though here we often return
That depends on what you write. See above. |
But that's not at all relevant. A poison error happens when some other task / thread first panics while holding the same log, and that's the error you will want to debug, not further tasks failing because the initial panic poisoned a lock.
Sure.
That's the thing – it doesn't (except through knowing which lock it was). The relevant panic message / location is always the one from the panic that caused the lock to be poisoned in the first place, not the message / location of the next thread trying to acquire the same lock and failing. |
that's already worth a lot, if the code you look at is: .sync_with_callback(sync_settings, |sync_response| async {
if !state.read().unwrap().has_first_synced {
state.write().unwrap().has_first_synced = true;
}
if state.read().unwrap().should_stop_syncing {
state.write().unwrap().is_syncing = false;
return LoopCtrl::Break;
} else if !state.read().unwrap().is_syncing {
state.write().unwrap().is_syncing = true;
}
if let Some(delegate) = &*delegate.read().unwrap() {
delegate.did_receive_sync_update()
} or *self.client.write().unwrap() = Some(client);
*self.homeserver_details.write().unwrap() = Some(details); |
Agreed. Ideally, that is true. But if that happens outside of rust, e.g. with delegate in the outer environment, and then they call the following function, the only thing they will tell us I am saying in FFI or any other embedded env, we might not have the luxury of being informed about these properly as "we have dealt with the issue", leaving a dangling lock on our side and all we get are the breadcrumbs we leave ourselves... |
No, not just ideally. There is no way non-Rust code can poison a Rust mutex. |
I honestly don't know the std Mutex enough and reading the code it isn't entirely clear to me, if that is true - the panicking-code isn't that obvious to follow for ffi-cases. I wonder where you get that confidence from. Is it because if the thread is failing outside of the FFI callback, the So, if I read this correctly, for neither If that is what it is, then ... okay... We should probably clearly document on the delegates that if they fail and cause the thread to unwind, we are not able to continue operation and will run into a halt without any error soon after. It's not something I'd necessarily expect to happen ... But then yeah, if you really feel that strongly about having |
75812ef
to
0fdd4fc
Compare
Unfortunately we still always pull in parking_lot 0.11 (sled, wasm-timer) which I suspect is not really needed, plus parking_lot 0.12 (but only on
target_os = "linux"
when checking / buildingbenchmarks
). That is, the overall reduction in dependencies is very small, but at least the parking_lot 0.12 dependency for wasm and macos through the examples is gone, so it should speed up those CI jobs a little bit.