-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for deleted volumes during region replacement #6659
Changes from 1 commit
4c83c6d
7343fe7
a3ff716
5cfc566
ed5d00b
7f998a0
a38b751
0c52969
e5f9eae
66e6678
08786cc
c132101
aefcf54
383d87c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,27 +8,27 @@ use crate::http_testing::NexusRequest; | |
use dropshot::test_util::ClientTestContext; | ||
use nexus_client::types::BackgroundTask; | ||
use nexus_client::types::CurrentStatus; | ||
use nexus_client::types::CurrentStatusRunning; | ||
use nexus_client::types::LastResult; | ||
use nexus_client::types::LastResultCompleted; | ||
use nexus_types::internal_api::background::*; | ||
use omicron_test_utils::dev::poll::{wait_for_condition, CondCheckError}; | ||
use std::time::Duration; | ||
|
||
/// Return the most recent start time for a background task | ||
fn most_recent_start_time( | ||
/// Return the most recent activate time for a background task, returning None | ||
/// if it has never been started or is currently running. | ||
fn most_recent_activate_time( | ||
task: &BackgroundTask, | ||
) -> Option<chrono::DateTime<chrono::Utc>> { | ||
match task.current { | ||
CurrentStatus::Idle => match task.last { | ||
LastResult::Completed(LastResultCompleted { | ||
start_time, .. | ||
}) => Some(start_time), | ||
|
||
LastResult::NeverCompleted => None, | ||
}, | ||
CurrentStatus::Running(CurrentStatusRunning { start_time, .. }) => { | ||
Some(start_time) | ||
} | ||
|
||
CurrentStatus::Running(..) => None, | ||
} | ||
} | ||
|
||
|
@@ -45,7 +45,7 @@ pub async fn activate_background_task( | |
.execute_and_parse_unwrap::<BackgroundTask>() | ||
.await; | ||
|
||
let last_start = most_recent_start_time(&task); | ||
let last_activate = most_recent_activate_time(&task); | ||
|
||
internal_client | ||
.make_request( | ||
|
@@ -69,10 +69,45 @@ pub async fn activate_background_task( | |
.execute_and_parse_unwrap::<BackgroundTask>() | ||
.await; | ||
|
||
if matches!(&task.current, CurrentStatus::Idle) | ||
&& most_recent_start_time(&task) > last_start | ||
{ | ||
Ok(task) | ||
// Wait until the task has actually run and then is idle | ||
if matches!(&task.current, CurrentStatus::Idle) { | ||
let current_activate = most_recent_activate_time(&task); | ||
match (current_activate, last_activate) { | ||
(None, None) => { | ||
// task is idle but it hasn't started yet, and it was | ||
// never previously activated | ||
Err(CondCheckError::<()>::NotYet) | ||
} | ||
|
||
(Some(_), None) => { | ||
// task was activated for the first time by this | ||
// function call, and it's done now (because the task is | ||
// idle) | ||
Ok(task) | ||
} | ||
|
||
(None, Some(_)) => { | ||
// the task is idle (due to the check above) but | ||
// `most_recent_activate_time` returned None, implying | ||
// that the LastResult is NeverCompleted? the Some in | ||
// the second part of the tuple means this ran before, | ||
// so panic here. | ||
panic!("task is idle, but there's no activate time?!"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We panic here because this should not be possible, right? Is there any chance the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The state of the background task could change yeah but we'll pick that up when it gets re-polled. The state of the world in that part of the |
||
} | ||
|
||
(Some(current_activation), Some(last_activation)) => { | ||
// the task is idle, it started ok, and it was | ||
// previously activated: compare times to make sure we | ||
// didn't observe the same BackgroundTask object | ||
if current_activation > last_activation { | ||
Ok(task) | ||
} else { | ||
// the task hasn't started yet, we observed the same | ||
// BackgroundTask object | ||
Err(CondCheckError::<()>::NotYet) | ||
} | ||
} | ||
} | ||
} else { | ||
Err(CondCheckError::<()>::NotYet) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is my understanding correct that this is returning:
You only get a
Some
here if the task has completed at least once and is not currently running?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, yeah.