diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 367cdea1cc..914eb75108 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -2779,7 +2779,7 @@ impl TenantShard { &self.cancel, ) .await - .unwrap(); + .map_err(|e| CreateTimelineError::Other(e.into()))?; tracing::info!( "downloaded template index_part.json with generation {}", @@ -2832,7 +2832,8 @@ impl TenantShard { .collect(); unfinished_timeline .layers - .blocking_write() + .write() + .await .open_mut() .map_err(|_| CreateTimelineError::ShuttingDown)? .initialize_local_layers(layers, template_metadata.disk_consistent_lsn()); diff --git a/pageserver/src/tenant/remote_timeline_client/download.rs b/pageserver/src/tenant/remote_timeline_client/download.rs index 3027af5816..3150d208ad 100644 --- a/pageserver/src/tenant/remote_timeline_client/download.rs +++ b/pageserver/src/tenant/remote_timeline_client/download.rs @@ -396,6 +396,32 @@ async fn do_download_index_part( Ok((index_part, index_generation, index_part_mtime)) } +async fn do_download_template_index_part( + storage: &GenericRemoteStorage, + tenant_shard_id: &TenantShardId, + timeline_id: Option<&TimelineId>, + index_generation: Generation, + cancel: &CancellationToken, +) -> Result<(IndexPart, Generation, SystemTime), DownloadError> { + let timeline_id = + timeline_id.expect("A timeline ID is always provided when downloading an index"); + let remote_path = remote_template_index_path(tenant_shard_id, timeline_id, index_generation); + + let download_opts = DownloadOpts { + kind: DownloadKind::Small, + ..Default::default() + }; + + let (index_part_bytes, index_part_mtime) = + do_download_remote_path_retry_forever(storage, &remote_path, download_opts, cancel).await?; + + let index_part: IndexPart = serde_json::from_slice(&index_part_bytes) + .with_context(|| format!("deserialize index part file at {remote_path:?}")) + .map_err(DownloadError::Other)?; + + Ok((index_part, index_generation, index_part_mtime)) +} + /// Metadata objects are "generationed", meaning that they include a generation suffix. This /// function downloads the object with the highest generation <= `my_generation`. /// @@ -584,7 +610,7 @@ pub(crate) async fn download_template_index_part( my_generation, "index_part", index_prefix, - do_download_index_part, + do_download_template_index_part, parse_remote_index_path, cancel, )