Skip to content

Commit c7b5a8d

Browse files
committed
refactor: 🔒 Narrow scope of usage of read and write locks to forest and file storage
1 parent 68c2a02 commit c7b5a8d

File tree

3 files changed

+43
-26
lines changed

3 files changed

+43
-26
lines changed

client/src/tasks/bsp_download_file.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,26 @@ where
6868
chunk_ids,
6969
request_id,
7070
bucket_id,
71+
file_key,
7172
..
7273
} = event;
7374

74-
// Get the file metadata from the file storage.
75-
let file_storage_read_lock = self.storage_hub_handler.file_storage.read().await;
76-
let file_metadata = file_storage_read_lock
77-
.get_metadata(&event.file_key.into())
78-
.map_err(|_| anyhow::anyhow!("Failed to get file metadata"))?;
75+
let file_key_hash = file_key.into();
7976

80-
// If the file metadata is not found, return an error.
81-
let file_metadata = if let Some(file_metadata) = file_metadata {
82-
file_metadata
83-
} else {
84-
error!(target: LOG_TARGET, "File not found in file storage");
85-
return Err(anyhow::anyhow!("File not found in file storage"));
77+
// Get the file metadata from the file storage within a short-lived read lock.
78+
let file_metadata = {
79+
let file_storage_read_lock = self.storage_hub_handler.file_storage.read().await;
80+
let file_metadata = file_storage_read_lock
81+
.get_metadata(&file_key_hash)
82+
.map_err(|_| anyhow::anyhow!("Failed to get file metadata"))?;
83+
84+
// If the file metadata is not found, return an error.
85+
if let Some(file_metadata) = file_metadata {
86+
file_metadata
87+
} else {
88+
error!(target: LOG_TARGET, "File not found in file storage");
89+
return Err(anyhow::anyhow!("File not found in file storage"));
90+
}
8691
};
8792

8893
// If we have a bucket ID in the request, check if the file bucket matches the bucket ID in
@@ -92,15 +97,20 @@ where
9297
error!(
9398
target: LOG_TARGET,
9499
"File bucket mismatch for file {:?}: expected {:?}, got {:?}",
95-
event.file_key, file_metadata.bucket_id(), bucket_id
100+
file_key,
101+
file_metadata.bucket_id(),
102+
bucket_id
96103
);
97104
return Err(anyhow::anyhow!("File bucket mismatch"));
98105
}
99106
}
100107

101-
// Generate the proof for the chunk (which also contains the chunk data itself).
102-
let generate_proof_result =
103-
file_storage_read_lock.generate_proof(&event.file_key.into(), &chunk_ids);
108+
// Generate the proof for the chunk (which also contains the chunk data itself) within a
109+
// short-lived read lock, then drop the lock before performing any network I/O.
110+
let generate_proof_result = {
111+
let file_storage_read_lock = self.storage_hub_handler.file_storage.read().await;
112+
file_storage_read_lock.generate_proof(&file_key_hash, &chunk_ids)
113+
};
104114

105115
match generate_proof_result {
106116
Ok(file_key_proof) => {
@@ -118,7 +128,7 @@ where
118128

119129
Ok(format!(
120130
"Handled RemoteDownloadRequest [{:?}] for file [{:x}]",
121-
request_id, event.file_key
131+
request_id, file_key
122132
))
123133
}
124134
}

client/src/tasks/bsp_upload_file.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ where
341341
let read_file_storage = self.storage_hub_handler.file_storage.read().await;
342342
let mut file_keys_and_proofs = Vec::new();
343343
let mut file_metadatas = HashMap::new();
344+
let mut requests_to_retry = Vec::new();
344345
for (confirm_storing_request, chunks_to_prove) in
345346
confirm_storing_requests_with_chunks_to_prove.into_iter()
346347
{
@@ -365,17 +366,22 @@ where
365366
error!(target: LOG_TARGET, "Failed to generate proof or get metadatas for file {:?}.\nMax try count exceeded! Dropping request!", confirm_storing_request.file_key);
366367
} else {
367368
error!(target: LOG_TARGET, "Failed to generate proof or get metadatas for file {:?}.\nEnqueuing file key again! (retry {}/{})", confirm_storing_request.file_key, confirm_storing_request.try_count, self.config.max_try_count);
368-
self.storage_hub_handler
369-
.blockchain
370-
.queue_confirm_bsp_request(confirm_storing_request)
371-
.await?;
369+
requests_to_retry.push(confirm_storing_request);
372370
}
373371
}
374372
}
375373
}
376374
// Release the file storage read lock as soon as possible.
377375
drop(read_file_storage);
378376

377+
// Re-enqueue any requests that we could not process, now that the file storage lock is dropped.
378+
for confirm_storing_request in requests_to_retry {
379+
self.storage_hub_handler
380+
.blockchain
381+
.queue_confirm_bsp_request(confirm_storing_request)
382+
.await?;
383+
}
384+
379385
if file_keys_and_proofs.is_empty() {
380386
error!(target: LOG_TARGET, "Failed to generate proofs for ALL the requested files.\n");
381387
return Err(anyhow!(

client/src/tasks/msp_upload_file.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,11 @@ where
305305

306306
let mut file_key_responses = HashMap::new();
307307

308-
let read_file_storage = self.storage_hub_handler.file_storage.read().await;
309-
310308
for respond in &event.data.respond_storing_requests {
311309
info!(target: LOG_TARGET, "Processing respond storing request.");
310+
311+
let read_file_storage = self.storage_hub_handler.file_storage.read().await;
312+
312313
let bucket_id = match read_file_storage.get_metadata(&respond.file_key) {
313314
Ok(Some(metadata)) => H256::from_slice(metadata.bucket_id().as_ref()),
314315
Ok(None) => {
@@ -364,8 +365,6 @@ where
364365
}
365366
}
366367

367-
drop(read_file_storage);
368-
369368
let mut storage_request_msp_response = Vec::new();
370369

371370
for (bucket_id, (accept, reject)) in file_key_responses.iter_mut() {
@@ -577,11 +576,13 @@ where
577576
.forest_storage_handler
578577
.get_or_create(&ForestStorageKey::from(event.bucket_id.as_ref().to_vec()))
579578
.await;
580-
let read_fs = fs.read().await;
581579

582580
// If we do not have the file already in forest storage, we must take into account the
583581
// available storage capacity.
584-
let file_in_forest_storage = read_fs.contains_file_key(&file_key.into())?;
582+
let file_in_forest_storage = {
583+
let read_fs = fs.read().await;
584+
read_fs.contains_file_key(&file_key.into())?
585+
};
585586
if !file_in_forest_storage {
586587
info!(target: LOG_TARGET, "File key [{:x}] not found in forest storage. Checking available storage capacity.", file_key);
587588

0 commit comments

Comments
 (0)