Skip to content

Commit ff4b9b6

Browse files
authored
Don't hold DashMap lock over await points. (#4138)
## Motivation The ScyllaDB tests currently hang on main because we hold a `DashMap` lock across an `await` point. ## Proposal Don't. ## Test Plan This fixed the ScyllaDB deadlock for me locally. ## Release Plan - Nothing to do / These changes follow the usual release cycle. ## Links - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
1 parent 3524ba5 commit ff4b9b6

File tree

1 file changed

+32
-36
lines changed

1 file changed

+32
-36
lines changed

linera-views/src/backends/scylla_db.rs

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::{
1414
};
1515

1616
use async_lock::{Semaphore, SemaphoreGuard};
17-
use dashmap::{mapref::entry::Entry, DashMap};
17+
use dashmap::DashMap;
1818
use futures::{future::join_all, StreamExt as _};
1919
use linera_base::ensure;
2020
use scylla::{
@@ -240,48 +240,44 @@ impl ScyllaDbClient {
240240
&self,
241241
num_markers: usize,
242242
) -> Result<PreparedStatement, ScyllaDbStoreInternalError> {
243-
let entry = self.multi_key_values.entry(num_markers);
244-
match entry {
245-
Entry::Occupied(entry) => Ok(entry.get().clone()),
246-
Entry::Vacant(entry) => {
247-
let markers = std::iter::repeat_n("?", num_markers)
248-
.collect::<Vec<_>>()
249-
.join(",");
250-
let prepared_statement = self
251-
.session
252-
.prepare(format!(
253-
"SELECT k,v FROM {}.{} WHERE root_key = ? AND k IN ({})",
254-
KEYSPACE, self.namespace, markers
255-
))
256-
.await?;
257-
entry.insert(prepared_statement.clone());
258-
Ok(prepared_statement)
259-
}
243+
if let Some(prepared_statement) = self.multi_key_values.get(&num_markers) {
244+
return Ok(prepared_statement.clone());
260245
}
246+
let markers = std::iter::repeat_n("?", num_markers)
247+
.collect::<Vec<_>>()
248+
.join(",");
249+
let prepared_statement = self
250+
.session
251+
.prepare(format!(
252+
"SELECT k,v FROM {}.{} WHERE root_key = ? AND k IN ({})",
253+
KEYSPACE, self.namespace, markers
254+
))
255+
.await?;
256+
self.multi_key_values
257+
.insert(num_markers, prepared_statement.clone());
258+
Ok(prepared_statement)
261259
}
262260

263261
async fn get_multi_keys_statement(
264262
&self,
265263
num_markers: usize,
266264
) -> Result<PreparedStatement, ScyllaDbStoreInternalError> {
267-
let entry = self.multi_keys.entry(num_markers);
268-
match entry {
269-
Entry::Occupied(entry) => Ok(entry.get().clone()),
270-
Entry::Vacant(entry) => {
271-
let markers = std::iter::repeat_n("?", num_markers)
272-
.collect::<Vec<_>>()
273-
.join(",");
274-
let prepared_statement = self
275-
.session
276-
.prepare(format!(
277-
"SELECT k FROM {}.{} WHERE root_key = ? AND k IN ({})",
278-
KEYSPACE, self.namespace, markers
279-
))
280-
.await?;
281-
entry.insert(prepared_statement.clone());
282-
Ok(prepared_statement)
283-
}
284-
}
265+
if let Some(prepared_statement) = self.multi_keys.get(&num_markers) {
266+
return Ok(prepared_statement.clone());
267+
};
268+
let markers = std::iter::repeat_n("?", num_markers)
269+
.collect::<Vec<_>>()
270+
.join(",");
271+
let prepared_statement = self
272+
.session
273+
.prepare(format!(
274+
"SELECT k FROM {}.{} WHERE root_key = ? AND k IN ({})",
275+
KEYSPACE, self.namespace, markers
276+
))
277+
.await?;
278+
self.multi_keys
279+
.insert(num_markers, prepared_statement.clone());
280+
Ok(prepared_statement)
285281
}
286282

287283
fn check_key_size(key: &[u8]) -> Result<(), ScyllaDbStoreInternalError> {

0 commit comments

Comments
 (0)