-
Type: Bug
-
Resolution: Fixed
-
Priority: Critical - P2
-
Affects Version/s: 1.2.0, 2.0.0-alpha
-
Component/s: None
-
None
The driver deadlocks when performing a retry when all connections are checked out from the pool. This is due to the fact that the connection used in the first attempt is not dropped before attempting the retry.
repro:
Unable to find source-code formatter for language: rust. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
#[cfg_attr(feature = "tokio-runtime", tokio::test(flavor = "multi_thread"))] #[cfg_attr(feature = "async-std-runtime", async_std::test)] async fn deadlock_test() { let _guard: RwLockWriteGuard<()> = LOCK.run_exclusively().await; let mut client_options = CLIENT_OPTIONS.clone(); client_options.hosts.drain(1..); client_options.direct_connection = Some(true); client_options.repl_set_name = None; client_options.retry_reads = Some(true); client_options.max_pool_size = Some(1); let client = TestClient::with_options(Some(client_options.clone()), true).await; if !client.supports_fail_command().await { println!("skipping {} due to failCommand not being supported", "ok"); return; } let collection = client.database("ok").collection("ok"); collection.insert_one(doc! { "x": 1 }, None).await.unwrap(); let options = FailCommandOptions::builder() .error_code(91) .build(); let failpoint = FailPoint::fail_command(&["find"], FailPointMode::Times(1), Some(options)); let _fp_guard = client.enable_failpoint(failpoint, None).await.unwrap(); let mut tasks: Vec<AsyncJoinHandle<_>> = Vec::new(); for _ in 0..2 { let coll = collection.clone(); let task = RUNTIME .spawn(async move { coll.find_one(doc! {}, None).await }) .unwrap(); tasks.push(task); } futures::future::join_all(tasks) .await .into_iter() .collect::<Result<Vec<_>>>() .expect("all should succeeed"); }