From fa947f0f4f79607969d12b99e2c5b9fbf9ab38e0 Mon Sep 17 00:00:00 2001 From: Joonas Koivunen Date: Fri, 5 May 2023 02:40:15 +0300 Subject: [PATCH] fix: resubscribe while holding the lock --- pageserver/src/tenant.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 9b9439048e..f2a0f647b9 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -1450,7 +1450,7 @@ impl Tenant { // need to synchronize and cannot be original semi-lockless algorithm for "upload // indexpart" part, we create a single task to delete the timeline. - let rx = { + let mut rx = { let mut g = timeline.delete_self.lock().await; let maybe_rx = if let Some(maybe_done) = g.as_ref() { use timeline::MaybeDone; @@ -1523,12 +1523,15 @@ impl Tenant { *g = Some(timeline::MaybeDone::Pending(Arc::downgrade(&rx))); rx } + // subscribe while the mutex is held, so we are guaranteed to receive the message, + // unless a panic comes. + .resubscribe() }; { use tokio::sync::broadcast::error::RecvError; - match rx.resubscribe().recv().await { + match rx.recv().await { Ok(Ok(())) => Ok(()), Ok(Err(e)) => Err(DeleteTimelineError::from(&e)), // lagged doesn't mean anything with 1 send, but whatever, handle it the same