mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-01 02:04:24 +00:00
Wait for the managed run to settle before the prune scenario deletes it
The stored view reports a Petri run ended as soon as its own run.finished record is folded, which is before the server stores the terminal lifecycle record and settles the managed run in its map. The delete precheck reads that map, so a delete sent as soon as the API reports the run ended can be refused as active instead of by the held lease. The scenario now waits for the managed run to settle, through a test-support accessor for its status, before it deletes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
9edbacfd5c
commit
9a93bbcfbd
2 changed files with 31 additions and 0 deletions
|
|
@ -1201,6 +1201,19 @@ impl AppState {
|
|||
&self.petri_projector
|
||||
}
|
||||
|
||||
/// The status the server holds for a managed run, so a test can wait
|
||||
/// for the run to settle in the server's own map (what the delete
|
||||
/// precheck reads) and not only in the stored view, which can report
|
||||
/// the run ended first.
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
#[must_use]
|
||||
pub fn test_managed_run_status(&self, run_id: &RunId) -> Option<RunStatus> {
|
||||
self.runs
|
||||
.lock()
|
||||
.ok()
|
||||
.and_then(|runs| runs.get(run_id).map(|managed_run| managed_run.status))
|
||||
}
|
||||
|
||||
/// The pool the Petri view tables live in, so a test can read them.
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn test_petri_view_pool(&self) -> DbPool {
|
||||
|
|
|
|||
|
|
@ -802,6 +802,9 @@ async fn deleting_a_run_prunes_its_host_workspace_through_petri() {
|
|||
let store = state.test_petri_run_store();
|
||||
let key = RunKey::new(run_id.clone());
|
||||
wait_for_free_lease(store, &key).await;
|
||||
// The view reports the run ended from Petri's own finish, before the
|
||||
// server settles the managed run the delete precheck reads.
|
||||
wait_for_managed_settle(&state, &run_id).await;
|
||||
|
||||
// A live handle on the run, as its worker holds one, refuses the
|
||||
// delete: Petri will not prune under a lease someone holds.
|
||||
|
|
@ -858,6 +861,21 @@ async fn deleting_a_run_prunes_its_host_workspace_through_petri() {
|
|||
}
|
||||
|
||||
/// Wait until no owner holds the run's lease.
|
||||
/// Wait until the server's own map holds the run as ended.
|
||||
async fn wait_for_managed_settle(state: &AppState, run_id: &str) {
|
||||
let run_id: RunId = run_id.parse().expect("a run id");
|
||||
for _ in 0..500 {
|
||||
if state
|
||||
.test_managed_run_status(&run_id)
|
||||
.is_none_or(|status| status.is_terminal())
|
||||
{
|
||||
return;
|
||||
}
|
||||
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||
}
|
||||
panic!("the managed run did not settle");
|
||||
}
|
||||
|
||||
async fn wait_for_free_lease(store: &SqliteRunStore, key: &RunKey) {
|
||||
for _ in 0..500 {
|
||||
if store.owner(key).await.expect("reads the lease").is_none() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue