-
Notifications
You must be signed in to change notification settings - Fork 638
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
Make sure all arbiters are joined #4841
Comments
cc @mina86, IIRC, you did some work on the tests which were flaky due to database not being properly closed by the end of the test. This might be (or not be) related to that. |
I don’t recall working on tests but this may be related to #3266 |
Related to #5340 |
This issue has been automatically marked as stale because it has not had recent activity in the last 2 months. |
I think we don't have acute problem with DB not being closed properly anymore, thanks to our diff --git a/core/store/src/db/rocksdb.rs b/core/store/src/db/rocksdb.rs
index 280c33ae1..debd3bcc1 100644
--- a/core/store/src/db/rocksdb.rs
+++ b/core/store/src/db/rocksdb.rs
@@ -453,6 +453,20 @@ pub(crate) static ROCKSDB_INSTANCES_COUNTER: Lazy<(Mutex<usize>, Condvar)> =
Lazy::new(|| (Mutex::new(0), Condvar::new()));
impl RocksDB {
+ pub fn db_leak_guard() -> impl Drop {
+ struct Guard;
+
+ impl Drop for Guard {
+ fn drop(&mut self) {
+ if !std::thread::panicking() {
+ assert_eq!(*ROCKSDB_INSTANCES_COUNTER.0.lock().unwrap(), 0);
+ }
+ }
+ }
+ assert_eq!(*ROCKSDB_INSTANCES_COUNTER.0.lock().unwrap(), 0);
+ Guard
+ }
+
/// Blocks until all RocksDB instances (usually 0 or 1) gracefully shutdown.
pub fn block_until_all_instances_are_dropped() {
let (lock, cvar) = &*ROCKSDB_INSTANCES_COUNTER;
@@ -556,6 +570,7 @@ impl Drop for RocksDB {
env.set_background_threads(4);
}
self.db.cancel_all_background_work(true);
+ std::thread::sleep(std::time::Duration::from_millis(25));
}
} It's rather easy to add that to tests, and to run them with No action required, just something we might need in the future if this resurfaces. |
In a bunch of places , we create new actix arbiters:
An
Arbiter
is basically astd::thread::JoinHandle
, and it is a best practice to make sure that they are joined. There's a Tolstoy-length novel [blog post](https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/) about the general issue, but the TL;DR in Rust context is:main
function returns. If there are some still running threads, they are abruptly terminated. In particular,Drop
s are not invokes, and so things likeBufWriter
may fail to flush the data.I suggest auditing all calls to
Arbiter::new
and making sure that something joins the arbiters in the end. Often,the most convenient place for that is Drop:Not that Arbiter has two "stopping" methods – the
stop
asyncronously asks arbiter to stop, while.join()
actually waits for the work to complete. I think we need to use both.The text was updated successfully, but these errors were encountered: