LCOV - code coverage report
Current view: top level - pageserver/src/tenant/timeline - offload.rs (source / functions) Coverage Total Hit
Test: b4ae4c4857f9ef3e144e982a35ee23bc84c71983.info Lines: 0.0 % 48 0
Test Date: 2024-10-22 22:13:45 Functions: 0.0 % 5 0

            Line data    Source code
       1              : use std::sync::Arc;
       2              : 
       3              : use crate::tenant::{OffloadedTimeline, Tenant, TimelineOrOffloaded};
       4              : 
       5              : use super::{
       6              :     delete::{delete_local_timeline_directory, DeleteTimelineFlow, DeletionGuard},
       7              :     Timeline,
       8              : };
       9              : 
      10            0 : pub(crate) async fn offload_timeline(
      11            0 :     tenant: &Tenant,
      12            0 :     timeline: &Arc<Timeline>,
      13            0 : ) -> anyhow::Result<()> {
      14            0 :     tracing::info!("offloading archived timeline");
      15            0 :     let (timeline, guard) = DeleteTimelineFlow::prepare(tenant, timeline.timeline_id)?;
      16              : 
      17            0 :     let TimelineOrOffloaded::Timeline(timeline) = timeline else {
      18            0 :         tracing::error!("timeline already offloaded, but given timeline object");
      19            0 :         return Ok(());
      20              :     };
      21              : 
      22              :     // Now that the Timeline is in Stopping state, request all the related tasks to shut down.
      23            0 :     timeline.shutdown(super::ShutdownMode::Hard).await;
      24              : 
      25              :     // TODO extend guard mechanism above with method
      26              :     // to make deletions possible while offloading is in progress
      27              : 
      28              :     // TODO mark timeline as offloaded in S3
      29              : 
      30            0 :     let conf = &tenant.conf;
      31            0 :     delete_local_timeline_directory(conf, tenant.tenant_shard_id, &timeline).await?;
      32              : 
      33            0 :     remove_timeline_from_tenant(tenant, &timeline, &guard).await?;
      34              : 
      35            0 :     {
      36            0 :         let mut offloaded_timelines = tenant.timelines_offloaded.lock().unwrap();
      37            0 :         offloaded_timelines.insert(
      38            0 :             timeline.timeline_id,
      39            0 :             Arc::new(OffloadedTimeline::from_timeline(&timeline)),
      40            0 :         );
      41            0 :     }
      42            0 : 
      43            0 :     Ok(())
      44            0 : }
      45              : 
      46              : /// It is important that this gets called when DeletionGuard is being held.
      47              : /// For more context see comments in [`DeleteTimelineFlow::prepare`]
      48            0 : async fn remove_timeline_from_tenant(
      49            0 :     tenant: &Tenant,
      50            0 :     timeline: &Timeline,
      51            0 :     _: &DeletionGuard, // using it as a witness
      52            0 : ) -> anyhow::Result<()> {
      53            0 :     // Remove the timeline from the map.
      54            0 :     let mut timelines = tenant.timelines.lock().unwrap();
      55            0 :     let children_exist = timelines
      56            0 :         .iter()
      57            0 :         .any(|(_, entry)| entry.get_ancestor_timeline_id() == Some(timeline.timeline_id));
      58            0 :     // XXX this can happen because `branch_timeline` doesn't check `TimelineState::Stopping`.
      59            0 :     // We already deleted the layer files, so it's probably best to panic.
      60            0 :     // (Ideally, above remove_dir_all is atomic so we don't see this timeline after a restart)
      61            0 :     if children_exist {
      62            0 :         panic!("Timeline grew children while we removed layer files");
      63            0 :     }
      64            0 : 
      65            0 :     timelines
      66            0 :         .remove(&timeline.timeline_id)
      67            0 :         .expect("timeline that we were deleting was concurrently removed from 'timelines' map");
      68            0 : 
      69            0 :     drop(timelines);
      70            0 : 
      71            0 :     Ok(())
      72            0 : }
        

Generated by: LCOV version 2.1-beta