Switch to a new ActivityTree implementation.
This new implementation explicitly tracks the children of each node, eliminating many iterations through the full tree.
This commit is contained in:
284
src/nix_util/activity.rs
Normal file
284
src/nix_util/activity.rs
Normal file
@@ -0,0 +1,284 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use tracing::warn;
|
||||
|
||||
#[repr(u8)]
|
||||
pub(crate) enum Activity {
|
||||
Root(ActivityRoot),
|
||||
Unknown(ActivityUnknown),
|
||||
CopyPath(ActivityCopyPath),
|
||||
FileTransfer(ActivityFileTransfer),
|
||||
Realize(ActivityRealize),
|
||||
CopyPaths(ActivityCopyPaths),
|
||||
Builds(ActivityBuilds),
|
||||
Build(ActivityBuild),
|
||||
OptimizeStore(ActivityOptimizeStore),
|
||||
VerifyPaths(ActivityVerifyPaths),
|
||||
Substitute(ActivitySubstitute),
|
||||
QueryPathInfo(ActivityQueryPathInfo),
|
||||
PostBuildHook(ActivityPostBuildHook),
|
||||
BuildWaiting(ActivityBuildWaiting),
|
||||
FetchTree(ActivityFetchTree),
|
||||
}
|
||||
|
||||
impl Activity {
|
||||
pub(crate) fn stop(&mut self) -> () {
|
||||
match self {
|
||||
Activity::Root(_activity_root) => {
|
||||
panic!("Attempted to start root activity.");
|
||||
}
|
||||
Activity::Unknown(activity_unknown) => {
|
||||
activity_unknown.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::CopyPath(activity_copy_path) => {
|
||||
activity_copy_path.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::FileTransfer(activity_file_transfer) => {
|
||||
activity_file_transfer.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::Realize(activity_realize) => {
|
||||
activity_realize.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::CopyPaths(activity_copy_paths) => {
|
||||
activity_copy_paths.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::Builds(activity_builds) => {
|
||||
activity_builds.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::Build(activity_build) => {
|
||||
activity_build.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::OptimizeStore(activity_optimize_store) => {
|
||||
activity_optimize_store.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::VerifyPaths(activity_verify_paths) => {
|
||||
activity_verify_paths.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::Substitute(activity_substitute) => {
|
||||
activity_substitute.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::QueryPathInfo(activity_query_path_info) => {
|
||||
activity_query_path_info.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::PostBuildHook(activity_post_build_hook) => {
|
||||
activity_post_build_hook.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::BuildWaiting(activity_build_waiting) => {
|
||||
activity_build_waiting.state = ActivityState::Stopped;
|
||||
}
|
||||
Activity::FetchTree(activity_fetch_tree) => {
|
||||
activity_fetch_tree.state = ActivityState::Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_active(&self) -> bool {
|
||||
match self {
|
||||
Activity::Root(_activity_root) => true,
|
||||
Activity::Unknown(activity_unknown) => {
|
||||
matches!(activity_unknown.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::CopyPath(activity_copy_path) => {
|
||||
matches!(activity_copy_path.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::FileTransfer(activity_file_transfer) => {
|
||||
matches!(activity_file_transfer.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::Realize(activity_realize) => {
|
||||
matches!(activity_realize.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::CopyPaths(activity_copy_paths) => {
|
||||
matches!(activity_copy_paths.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::Builds(activity_builds) => {
|
||||
matches!(activity_builds.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::Build(activity_build) => {
|
||||
matches!(activity_build.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::OptimizeStore(activity_optimize_store) => {
|
||||
matches!(activity_optimize_store.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::VerifyPaths(activity_verify_paths) => {
|
||||
matches!(activity_verify_paths.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::Substitute(activity_substitute) => {
|
||||
matches!(activity_substitute.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::QueryPathInfo(activity_query_path_info) => {
|
||||
matches!(
|
||||
activity_query_path_info.state,
|
||||
ActivityState::Started { .. }
|
||||
)
|
||||
}
|
||||
Activity::PostBuildHook(activity_post_build_hook) => {
|
||||
matches!(
|
||||
activity_post_build_hook.state,
|
||||
ActivityState::Started { .. }
|
||||
)
|
||||
}
|
||||
Activity::BuildWaiting(activity_build_waiting) => {
|
||||
matches!(activity_build_waiting.state, ActivityState::Started { .. })
|
||||
}
|
||||
Activity::FetchTree(activity_fetch_tree) => {
|
||||
matches!(activity_fetch_tree.state, ActivityState::Started { .. })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_transparent(&self) -> bool {
|
||||
match self {
|
||||
Activity::Root(_activity_root) => true,
|
||||
Activity::Unknown(_activity_unknown) => false,
|
||||
Activity::CopyPath(_activity_copy_path) => false,
|
||||
Activity::FileTransfer(_activity_file_transfer) => false,
|
||||
Activity::Realize(_activity_realize) => true,
|
||||
Activity::CopyPaths(_activity_copy_paths) => true,
|
||||
Activity::Builds(_activity_builds) => true,
|
||||
Activity::Build(_activity_build) => false,
|
||||
Activity::OptimizeStore(_activity_optimize_store) => false,
|
||||
Activity::VerifyPaths(_activity_verify_paths) => false,
|
||||
Activity::Substitute(_activity_substitute) => false,
|
||||
Activity::QueryPathInfo(_activity_query_path_info) => false,
|
||||
Activity::PostBuildHook(_activity_post_build_hook) => false,
|
||||
Activity::BuildWaiting(_activity_build_waiting) => true,
|
||||
Activity::FetchTree(_activity_fetch_tree) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn display_name(&self) -> Option<Cow<'_, str>> {
|
||||
match self {
|
||||
Activity::Root(_activity_root) => {
|
||||
warn!("Unexpected display of root activity.");
|
||||
Some(Cow::Borrowed("Root"))
|
||||
}
|
||||
Activity::Unknown(activity_unknown) => {
|
||||
Some(Cow::Owned(format!("Unknown({})", activity_unknown.text)))
|
||||
}
|
||||
Activity::CopyPath(activity_copy_path) => Some(Cow::Owned(format!(
|
||||
"CopyPath({} | {} -> {})",
|
||||
activity_copy_path.missing_path,
|
||||
activity_copy_path.source,
|
||||
activity_copy_path.destination
|
||||
))),
|
||||
Activity::FileTransfer(activity_file_transfer) => Some(Cow::Owned(format!(
|
||||
"FileTransfer({})",
|
||||
activity_file_transfer.url
|
||||
))),
|
||||
Activity::Realize(_activity_realize) => Some(Cow::Borrowed("Realize")),
|
||||
Activity::CopyPaths(activity_copy_paths) => Some(Cow::Owned(format!(
|
||||
"CopyPaths({})",
|
||||
activity_copy_paths.text
|
||||
))),
|
||||
Activity::Builds(_activity_builds) => Some(Cow::Borrowed("Builds")),
|
||||
Activity::Build(activity_build) => {
|
||||
if let Some(machine_name) = &activity_build.machine_name {
|
||||
Some(Cow::Owned(format!(
|
||||
"Build({}@{machine_name})",
|
||||
activity_build.drv_path
|
||||
)))
|
||||
} else {
|
||||
Some(Cow::Owned(format!("Build({})", activity_build.drv_path)))
|
||||
}
|
||||
}
|
||||
Activity::OptimizeStore(_activity_optimize_store) => {
|
||||
Some(Cow::Borrowed("OptimizeStore"))
|
||||
}
|
||||
Activity::VerifyPaths(_activity_verify_paths) => Some(Cow::Borrowed("VerifyPaths")),
|
||||
Activity::Substitute(_activity_substitute) => Some(Cow::Borrowed("Substitute")),
|
||||
Activity::QueryPathInfo(_activity_query_path_info) => {
|
||||
Some(Cow::Borrowed("QueryPathInfo"))
|
||||
}
|
||||
Activity::PostBuildHook(_activity_post_build_hook) => {
|
||||
Some(Cow::Borrowed("PostBuildHook"))
|
||||
}
|
||||
Activity::BuildWaiting(activity_build_waiting) => Some(Cow::Owned(format!(
|
||||
"BuildWaiting({:?} | {:?} | {})",
|
||||
activity_build_waiting.drv_path,
|
||||
activity_build_waiting.path_resolved,
|
||||
activity_build_waiting.text
|
||||
))),
|
||||
Activity::FetchTree(_activity_fetch_tree) => Some(Cow::Borrowed("FetchTree")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ActivityRoot {}
|
||||
pub(crate) struct ActivityUnknown {
|
||||
pub(crate) state: ActivityState,
|
||||
pub(crate) text: String,
|
||||
}
|
||||
pub(crate) struct ActivityCopyPath {
|
||||
pub(crate) state: ActivityState,
|
||||
pub(crate) missing_path: String,
|
||||
|
||||
/// The machine with the file(s)
|
||||
pub(crate) source: String,
|
||||
|
||||
/// The machine that is receiving the file(s)
|
||||
pub(crate) destination: String,
|
||||
}
|
||||
pub(crate) struct ActivityFileTransfer {
|
||||
pub(crate) state: ActivityState,
|
||||
pub(crate) url: String,
|
||||
}
|
||||
pub(crate) struct ActivityRealize {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
pub(crate) struct ActivityCopyPaths {
|
||||
pub(crate) state: ActivityState,
|
||||
pub(crate) text: String,
|
||||
}
|
||||
pub(crate) struct ActivityBuilds {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
pub(crate) struct ActivityBuild {
|
||||
pub(crate) state: ActivityState,
|
||||
pub(crate) drv_path: String,
|
||||
pub(crate) machine_name: Option<String>,
|
||||
}
|
||||
pub(crate) struct ActivityOptimizeStore {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
pub(crate) struct ActivityVerifyPaths {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
pub(crate) struct ActivitySubstitute {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
pub(crate) struct ActivityQueryPathInfo {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
pub(crate) struct ActivityPostBuildHook {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
pub(crate) struct ActivityBuildWaiting {
|
||||
pub(crate) state: ActivityState,
|
||||
pub(crate) text: String,
|
||||
pub(crate) drv_path: Option<String>,
|
||||
pub(crate) path_resolved: Option<String>,
|
||||
}
|
||||
pub(crate) struct ActivityFetchTree {
|
||||
pub(crate) state: ActivityState,
|
||||
}
|
||||
|
||||
pub(crate) enum ActivityState {
|
||||
Started {
|
||||
progress_numerator: u64,
|
||||
progress_denominator: u64,
|
||||
progress_running: u64,
|
||||
progress_failed: u64,
|
||||
},
|
||||
Stopped,
|
||||
}
|
||||
|
||||
impl Default for ActivityState {
|
||||
fn default() -> Self {
|
||||
ActivityState::Started {
|
||||
progress_numerator: 0,
|
||||
progress_denominator: 0,
|
||||
progress_running: 0,
|
||||
progress_failed: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user