Compare commits
4 Commits
7b19e43fce
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
606832f505
|
||
|
|
9083a09455
|
||
|
|
1cc53ba631
|
||
|
|
1f5c080138
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
/work
|
/work
|
||||||
/example_logs
|
/example_logs
|
||||||
|
TODO.org
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use std::fmt::Display;
|
|||||||
use std::num::TryFromIntError;
|
use std::num::TryFromIntError;
|
||||||
use std::str::Utf8Error;
|
use std::str::Utf8Error;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
use std::time::SystemTimeError;
|
||||||
|
|
||||||
use crate::nix_util::ActivityIdAlreadyInTreeError;
|
use crate::nix_util::ActivityIdAlreadyInTreeError;
|
||||||
use crate::nix_util::ActivityIdNotInTreeError;
|
use crate::nix_util::ActivityIdNotInTreeError;
|
||||||
@@ -24,6 +25,7 @@ pub(crate) enum CustomError {
|
|||||||
TryFromIntError(#[allow(dead_code)] TryFromIntError),
|
TryFromIntError(#[allow(dead_code)] TryFromIntError),
|
||||||
ActivityIdNotInTreeError(#[allow(dead_code)] ActivityIdNotInTreeError),
|
ActivityIdNotInTreeError(#[allow(dead_code)] ActivityIdNotInTreeError),
|
||||||
ActivityIdAlreadyInTreeError(#[allow(dead_code)] ActivityIdAlreadyInTreeError),
|
ActivityIdAlreadyInTreeError(#[allow(dead_code)] ActivityIdAlreadyInTreeError),
|
||||||
|
SystemTime(#[allow(dead_code)] SystemTimeError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for CustomError {
|
impl Display for CustomError {
|
||||||
@@ -127,3 +129,9 @@ impl From<ActivityIdAlreadyInTreeError> for CustomError {
|
|||||||
CustomError::ActivityIdAlreadyInTreeError(value)
|
CustomError::ActivityIdAlreadyInTreeError(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<SystemTimeError> for CustomError {
|
||||||
|
fn from(value: SystemTimeError) -> Self {
|
||||||
|
CustomError::SystemTime(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -202,6 +202,68 @@ impl Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_progress_text(&self) -> Option<Cow<'_, str>> {
|
||||||
|
match self {
|
||||||
|
Activity::Root(_activity_root) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a root activity.");
|
||||||
|
}
|
||||||
|
Activity::Unknown(_activity_unknown) => None,
|
||||||
|
Activity::CopyPath(activity_copy_path) => Some(Cow::Owned(format!(
|
||||||
|
"[{}/{}]",
|
||||||
|
activity_copy_path.done, activity_copy_path.expected
|
||||||
|
))),
|
||||||
|
Activity::FileTransfer(activity_file_transfer) => Some(Cow::Owned(format!(
|
||||||
|
"[{}/{}]",
|
||||||
|
activity_file_transfer.done, activity_file_transfer.expected
|
||||||
|
))),
|
||||||
|
Activity::Realize(_activity_realize) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a realize activity.");
|
||||||
|
}
|
||||||
|
Activity::CopyPaths(activity_copy_paths) => Some(Cow::Owned(format!(
|
||||||
|
"[{}/{}]",
|
||||||
|
activity_copy_paths.done, activity_copy_paths.expected
|
||||||
|
))),
|
||||||
|
Activity::Builds(activity_builds) => Some(Cow::Owned(format!(
|
||||||
|
"[{}/{}]",
|
||||||
|
activity_builds.done, activity_builds.expected
|
||||||
|
))),
|
||||||
|
Activity::Build(activity_build) => activity_build
|
||||||
|
.phase
|
||||||
|
.as_ref()
|
||||||
|
.map(|phase| Cow::Owned(format!("[{}]", phase))),
|
||||||
|
Activity::OptimizeStore(_activity_optimize_store) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a optimize store activity.");
|
||||||
|
}
|
||||||
|
Activity::VerifyPaths(_activity_verify_paths) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a verify paths activity.");
|
||||||
|
}
|
||||||
|
Activity::Substitute(_activity_substitute) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a substitute activity.");
|
||||||
|
}
|
||||||
|
Activity::QueryPathInfo(_activity_query_path_info) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a query path info activity.");
|
||||||
|
}
|
||||||
|
Activity::PostBuildHook(_activity_post_build_hook) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a post build hook activity.");
|
||||||
|
}
|
||||||
|
Activity::BuildWaiting(_activity_build_waiting) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a build waiting activity.");
|
||||||
|
}
|
||||||
|
Activity::FetchTree(_activity_fetch_tree) => {
|
||||||
|
// TODO
|
||||||
|
panic!("Attempted to get_progress_text of a fetch tree activity.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn set_phase(&mut self, phase: Option<String>) -> () {
|
pub(crate) fn set_phase(&mut self, phase: Option<String>) -> () {
|
||||||
match self {
|
match self {
|
||||||
Activity::Root(_activity_root) => {
|
Activity::Root(_activity_root) => {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ where
|
|||||||
"--show-trace",
|
"--show-trace",
|
||||||
"--max-jobs",
|
"--max-jobs",
|
||||||
"1",
|
"1",
|
||||||
|
"--repair",
|
||||||
"--log-format",
|
"--log-format",
|
||||||
"internal-json",
|
"internal-json",
|
||||||
"-vvvvvvvvvvv",
|
"-vvvvvvvvvvv",
|
||||||
|
|||||||
@@ -583,23 +583,23 @@ pub(crate) enum NixAction {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub(crate) struct MsgMessage {
|
pub(crate) struct MsgMessage {
|
||||||
level: u8,
|
pub(crate) level: u8,
|
||||||
msg: String,
|
pub(crate) msg: String,
|
||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
raw_msg: Option<String>,
|
pub(crate) raw_msg: Option<String>,
|
||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
file: Option<String>,
|
pub(crate) file: Option<String>,
|
||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
line: Option<u64>,
|
pub(crate) line: Option<u64>,
|
||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
column: Option<u64>,
|
pub(crate) column: Option<u64>,
|
||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
trace: Option<Vec<TraceEntry>>,
|
pub(crate) trace: Option<Vec<TraceEntry>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::time::Instant;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use sqlx::Row;
|
use sqlx::Row;
|
||||||
use tokio::process::Child;
|
use tokio::process::Child;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
@@ -35,6 +40,7 @@ use super::nix_output_stream::NixMessage;
|
|||||||
pub(crate) struct RunningBuild<'db> {
|
pub(crate) struct RunningBuild<'db> {
|
||||||
db_handle: &'db DbHandle,
|
db_handle: &'db DbHandle,
|
||||||
activity_tree: ActivityTree,
|
activity_tree: ActivityTree,
|
||||||
|
last_announce: Option<Instant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> RunningBuild<'db> {
|
impl<'db> RunningBuild<'db> {
|
||||||
@@ -42,6 +48,7 @@ impl<'db> RunningBuild<'db> {
|
|||||||
Ok(RunningBuild {
|
Ok(RunningBuild {
|
||||||
db_handle,
|
db_handle,
|
||||||
activity_tree: ActivityTree::new(),
|
activity_tree: ActivityTree::new(),
|
||||||
|
last_announce: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +60,8 @@ impl<'db> RunningBuild<'db> {
|
|||||||
where
|
where
|
||||||
TN: AsRef<str>,
|
TN: AsRef<str>,
|
||||||
{
|
{
|
||||||
|
let foo = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
|
||||||
|
let now = Instant::now();
|
||||||
let build_id: i64 = sqlx::query(
|
let build_id: i64 = sqlx::query(
|
||||||
r#"INSERT INTO build (start_time, target) SELECT unixepoch('now'), ? RETURNING id"#,
|
r#"INSERT INTO build (start_time, target) SELECT unixepoch('now'), ? RETURNING id"#,
|
||||||
)
|
)
|
||||||
@@ -110,7 +119,12 @@ impl<'db> RunningBuild<'db> {
|
|||||||
};
|
};
|
||||||
match message {
|
match message {
|
||||||
NixAction::Msg(msg_message) => {
|
NixAction::Msg(msg_message) => {
|
||||||
// For now we can ignore the messages.
|
if msg_message.msg.contains("nix log") {
|
||||||
|
eprintln!("{}", msg_message.msg);
|
||||||
|
}
|
||||||
|
// if msg_message.level == 0 {
|
||||||
|
// eprintln!("{}", msg_message.msg);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
NixAction::Start(activity_start_message) => {
|
NixAction::Start(activity_start_message) => {
|
||||||
match activity_start_message {
|
match activity_start_message {
|
||||||
@@ -269,7 +283,7 @@ impl<'db> RunningBuild<'db> {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// self.print_current_status();
|
self.print_current_status();
|
||||||
}
|
}
|
||||||
NixAction::Stop(stop_message) => {
|
NixAction::Stop(stop_message) => {
|
||||||
let activity = self
|
let activity = self
|
||||||
@@ -277,7 +291,7 @@ impl<'db> RunningBuild<'db> {
|
|||||||
.get_activity_id(stop_message.id)
|
.get_activity_id(stop_message.id)
|
||||||
.map(|activity_id| self.activity_tree.get_mut(&activity_id))?;
|
.map(|activity_id| self.activity_tree.get_mut(&activity_id))?;
|
||||||
activity.get_mut_activity().stop();
|
activity.get_mut_activity().stop();
|
||||||
// self.print_current_status();
|
self.print_current_status();
|
||||||
// println!("{}", serde_json::to_string(&message)?);
|
// println!("{}", serde_json::to_string(&message)?);
|
||||||
}
|
}
|
||||||
NixAction::Result(activity_result_message) => {
|
NixAction::Result(activity_result_message) => {
|
||||||
@@ -296,6 +310,8 @@ impl<'db> RunningBuild<'db> {
|
|||||||
activity
|
activity
|
||||||
.get_mut_activity()
|
.get_mut_activity()
|
||||||
.set_phase(Some(activity_result_set_phase.phase));
|
.set_phase(Some(activity_result_set_phase.phase));
|
||||||
|
|
||||||
|
self.print_current_status();
|
||||||
}
|
}
|
||||||
ActivityResultMessage::Progress(activity_result_progress) => {
|
ActivityResultMessage::Progress(activity_result_progress) => {
|
||||||
let activity_id = self
|
let activity_id = self
|
||||||
@@ -308,6 +324,8 @@ impl<'db> RunningBuild<'db> {
|
|||||||
activity_result_progress.running,
|
activity_result_progress.running,
|
||||||
activity_result_progress.failed,
|
activity_result_progress.failed,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.maybe_print_current_status();
|
||||||
}
|
}
|
||||||
ActivityResultMessage::SetExpected(activity_result_set_expected) => {
|
ActivityResultMessage::SetExpected(activity_result_set_expected) => {
|
||||||
let activity_id = self
|
let activity_id = self
|
||||||
@@ -317,6 +335,8 @@ impl<'db> RunningBuild<'db> {
|
|||||||
activity
|
activity
|
||||||
.get_mut_activity()
|
.get_mut_activity()
|
||||||
.set_expected(activity_result_set_expected.expected);
|
.set_expected(activity_result_set_expected.expected);
|
||||||
|
|
||||||
|
self.maybe_print_current_status();
|
||||||
}
|
}
|
||||||
ActivityResultMessage::PostBuildLogLine(
|
ActivityResultMessage::PostBuildLogLine(
|
||||||
_activity_result_post_build_log_line,
|
_activity_result_post_build_log_line,
|
||||||
@@ -328,7 +348,23 @@ impl<'db> RunningBuild<'db> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_current_status(&self) -> () {
|
fn maybe_print_current_status(&mut self) -> () {
|
||||||
|
let last_announce = match self.last_announce {
|
||||||
|
Some(instant) => instant,
|
||||||
|
None => {
|
||||||
|
// If we haven't announced before, always announce.
|
||||||
|
return self.print_current_status();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let now = Instant::now();
|
||||||
|
let time_since_last_announce = now.duration_since(last_announce);
|
||||||
|
if time_since_last_announce > Duration::new(5, 0) {
|
||||||
|
return self.print_current_status();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_current_status(&mut self) -> () {
|
||||||
let mut tree = String::new();
|
let mut tree = String::new();
|
||||||
let draw_order = self.get_draw_order();
|
let draw_order = self.get_draw_order();
|
||||||
for dag_entry in draw_order {
|
for dag_entry in draw_order {
|
||||||
@@ -353,15 +389,19 @@ impl<'db> RunningBuild<'db> {
|
|||||||
.get_activity()
|
.get_activity()
|
||||||
.display_name()
|
.display_name()
|
||||||
.expect("Currently we always return a display name.");
|
.expect("Currently we always return a display name.");
|
||||||
let activity_id = activity.get_activity_id();
|
let progress_text = activity.get_activity().get_progress_text();
|
||||||
let parent_id = activity.get_parent_id();
|
let (progress, progress_sep) = match progress_text {
|
||||||
tree += &format!("{leading_bars}{branch} {display_name} {parent_id} {activity_id}\n");
|
Some(text) => (text, " "),
|
||||||
|
None => (Cow::Borrowed(""), ""),
|
||||||
|
};
|
||||||
|
tree += &format!("{leading_bars}{branch} {progress}{progress_sep}{display_name}\n");
|
||||||
}
|
}
|
||||||
if tree.is_empty() {
|
if tree.is_empty() {
|
||||||
println!("No active activities.");
|
println!("No active activities.");
|
||||||
} else {
|
} else {
|
||||||
print!("\n{}\n", tree);
|
print!("\n{}\n", tree);
|
||||||
}
|
}
|
||||||
|
self.last_announce = Some(Instant::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_draw_order(&self) -> Vec<DrawDagEntry> {
|
fn get_draw_order(&self) -> Vec<DrawDagEntry> {
|
||||||
|
|||||||
Reference in New Issue
Block a user