Skip to content

Commit 363445f

Browse files
committed
tests need to wait for sagas to be enabled
1 parent 2be2c67 commit 363445f

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

nexus/src/app/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,14 @@ impl Nexus {
621621
}
622622
}
623623

624+
// Waits for Nexus to determine whether sagas are supposed to be quiesced
625+
//
626+
// This is used by the test suite because most tests assume that sagas are
627+
// operational as soon as they start.
628+
pub(crate) async fn wait_for_saga_determination(&self) {
629+
self.quiesce.sagas().wait_for_determination().await;
630+
}
631+
624632
pub(crate) async fn external_tls_config(
625633
&self,
626634
tls_enabled: bool,

nexus/src/app/quiesce.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ impl NexusQuiesceHandle {
9292
}
9393
});
9494

95+
// Immediately (synchronously) update the saga quiesce status. It's
96+
// okay to do this even if there wasn't a change.
97+
self.sagas.set_quiescing(quiescing);
98+
9599
if changed && quiescing {
96-
// Immediately quiesce sagas.
97-
self.sagas.set_quiescing(quiescing);
98100
// Asynchronously complete the rest of the quiesce process.
99-
if quiescing {
100-
tokio::spawn(do_quiesce(self.clone()));
101-
}
101+
tokio::spawn(do_quiesce(self.clone()));
102102
}
103103
}
104104
}

nexus/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,15 @@ impl Server {
138138
// the external server we're about to start.
139139
apictx.context.nexus.await_ip_allowlist_plumbing().await;
140140

141+
// Wait until Nexus has determined if sagas are supposed to be quiesced.
142+
// This is not strictly necessary. The goal here is to prevent 503
143+
// errors to clients that reach this Nexus while it's starting up and
144+
// before it's figured out that it doesn't need to quiesce. The risk of
145+
// doing this is that Nexus gets stuck here, but that should only happen
146+
// if it's unable to load the current blueprint, in which case
147+
// something's pretty wrong and it's likely pretty stuck anyway.
148+
apictx.context.nexus.wait_for_saga_determination().await;
149+
141150
// Launch the external server.
142151
let tls_config = apictx
143152
.context
@@ -332,6 +341,16 @@ impl nexus_test_interface::NexusServer for Server {
332341
.await
333342
.expect("Could not initialize rack");
334343

344+
// Now that we have a blueprint, determination of whether sagas are
345+
// quiesced can complete. Wait for that so that tests can assume they
346+
// can immediately kick off sagas.
347+
internal_server
348+
.apictx
349+
.context
350+
.nexus
351+
.wait_for_saga_determination()
352+
.await;
353+
335354
// Start the Nexus external API.
336355
Server::start(internal_server).await.unwrap()
337356
}

nexus/types/src/quiesce.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,18 @@ impl SagaQuiesceHandle {
218218
let _ = self.inner.subscribe().wait_for(|q| q.is_fully_drained()).await;
219219
}
220220

221+
/// Wait for the initial determination to be made about whether sagas are
222+
/// allowed or not.
223+
pub async fn wait_for_determination(&self) {
224+
let _ = self
225+
.inner
226+
.subscribe()
227+
.wait_for(|q| {
228+
q.new_sagas_allowed != SagasAllowed::DisallowedUnknown
229+
})
230+
.await;
231+
}
232+
221233
/// Returns information about running sagas (involves a clone)
222234
pub fn sagas_pending(&self) -> IdOrdMap<PendingSagaInfo> {
223235
self.inner.borrow().sagas_pending.clone()

0 commit comments

Comments
 (0)