mirror of
https://tangled.org/tranquil.farm/tranquil-pds
synced 2026-10-01 06:25:34 +00:00
tranquil-store/repo: repair tolerates corrupt/missing blocks
Lewis: May this revision serve well! <lu5a@proton.me>
This commit is contained in:
@@ -300,30 +300,18 @@ pub async fn repair_repo_structure(
|
||||
})?;
|
||||
|
||||
if outcome.nodes_repaired > 0 {
|
||||
let block_cids =
|
||||
crate::scheduled::collect_current_repo_blocks(&state.block_store, ¤t_root_cid)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("repair: re-walk for user_blocks backfill failed: {}", e);
|
||||
ApiError::InternalError(None)
|
||||
})?;
|
||||
|
||||
let cids = block_cids
|
||||
.iter()
|
||||
.map(|bytes| Cid::try_from(bytes.as_slice()))
|
||||
.collect::<Result<Vec<Cid>, _>>()
|
||||
.map_err(|e| {
|
||||
error!("repair: unparseable CID in repaired DAG walk: {e}");
|
||||
ApiError::InternalError(None)
|
||||
})?;
|
||||
let present = state.block_store.get_many(&cids).await.map_err(|e| {
|
||||
error!("repair: presence check during user_blocks backfill failed: {e}");
|
||||
let leaf_present = futures::future::try_join_all(
|
||||
entries.iter().map(|(_, cid)| state.block_store.has(cid)),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("repair: leaf presence check failed: {e}");
|
||||
ApiError::InternalError(None)
|
||||
})?;
|
||||
let missing: Vec<Cid> = cids
|
||||
let missing: Vec<Cid> = entries
|
||||
.iter()
|
||||
.zip(present)
|
||||
.filter_map(|(cid, found)| found.is_none().then_some(*cid))
|
||||
.zip(leaf_present)
|
||||
.filter_map(|((_, cid), present)| (!present).then_some(*cid))
|
||||
.collect();
|
||||
if !missing.is_empty() {
|
||||
error!(
|
||||
@@ -338,6 +326,14 @@ pub async fn repair_repo_structure(
|
||||
))));
|
||||
}
|
||||
|
||||
let block_cids =
|
||||
crate::scheduled::collect_current_repo_blocks(&state.block_store, ¤t_root_cid)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("repair: re-walk for user_blocks backfill failed: {}", e);
|
||||
ApiError::InternalError(None)
|
||||
})?;
|
||||
|
||||
state
|
||||
.repos
|
||||
.repo
|
||||
|
||||
@@ -180,6 +180,12 @@ pub async fn collect_current_repo_blocks(
|
||||
let block = match block_store.get(&cid).await {
|
||||
Ok(Some(b)) => b,
|
||||
Ok(None) => continue,
|
||||
Err(e)
|
||||
if crate::api::error::ApiError::detail_is_repo_corruption(&format!("{e:#}")) =>
|
||||
{
|
||||
warn!(cid = %cid, error = %format!("{e:#}"), "skipping corrupt block during repo walk");
|
||||
continue;
|
||||
}
|
||||
Err(e) => anyhow::bail!("Failed to get block {}: {:?}", cid, e),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user