Skip to content

Commit

Permalink
Clean up state reset and log handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Nukesor committed May 15, 2020
1 parent bff508a commit 6c5ab4d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 25 deletions.
4 changes: 2 additions & 2 deletions client/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use ::pueue::settings::Settings;

use crate::cli::{Opt, SubCommand};

// Convert and pre-process the sub-command into a valid message
// that can be understood by the daemon.
/// Convert the cli command into the message that's being sent to the server,
/// so it can be understood by the daemon.
pub fn get_message_from_opt(opt: &Opt, settings: &Settings) -> Result<Message> {
match &opt.cmd {
SubCommand::Add {
Expand Down
5 changes: 2 additions & 3 deletions daemon/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn handle_message(message: Message, sender: &Sender<Message>, state: &Shared
Message::Group(message) => group(message, state),

Message::Clean => clean(state),
Message::Reset => reset(sender, state),
Message::Reset => reset(sender),
Message::Status => get_status(state),
Message::Log(message) => get_log(message, state),
Message::Parallel(message) => set_parallel_tasks(message, state),
Expand Down Expand Up @@ -485,9 +485,8 @@ fn clean(state: &SharedState) -> Message {
/// Invoked when calling `pueue reset`.
/// Forward the reset request to the task handler.
/// The handler then kills all children and clears the task queue.
fn reset(sender: &Sender<Message>, state: &SharedState) -> Message {
fn reset(sender: &Sender<Message>) -> Message {
sender.send(Message::Reset).expect(SENDER_ERR);
clean(state);
create_success_message("Everything is being reset right now.")
}

Expand Down
4 changes: 4 additions & 0 deletions daemon/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ async fn main() -> Result<()> {

/// Initialize all directories needed for normal operation.
fn init_directories(path: &str) {
// Pueue base path
let pueue_dir = Path::new(path);
if !pueue_dir.exists() {
if let Err(error) = create_dir_all(&pueue_dir) {
Expand All @@ -77,6 +78,8 @@ fn init_directories(path: &str) {
);
}
}

// Task log dir
let log_dir = pueue_dir.join("log");
if !log_dir.exists() {
if let Err(error) = create_dir_all(&log_dir) {
Expand All @@ -87,6 +90,7 @@ fn init_directories(path: &str) {
}
}

// Task log dir
let logs_dir = pueue_dir.join("task_logs");
if !logs_dir.exists() {
if let Err(error) = create_dir_all(&logs_dir) {
Expand Down
32 changes: 17 additions & 15 deletions daemon/task_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ impl TaskHandler {
loop {
self.receive_commands();
self.handle_finished_tasks();
self.handle_reset();
self.check_callbacks();
self.check_stashed();
self.check_failed_dependencies();
Expand Down Expand Up @@ -180,6 +181,20 @@ impl TaskHandler {
.map(|(id, _)| *id)
}

/// Users can issue to reset the daemon.
/// If that's the case, the `self.reset` flag is set to true, all children are killed
/// and no new tasks will be spawned.
/// This function checks, if all killed children have been handled.
/// If that's the case, completely reset the state
fn handle_reset(&mut self) {
// The daemon got a reset request and all children already finished
if self.reset && self.children.is_empty() {
let mut state = self.state.lock().unwrap();
state.reset();
self.reset = false;
}
}

/// See if we can start a new queued task.
fn check_new(&mut self) -> Result<()> {
// Get the next task id that can be started
Expand Down Expand Up @@ -336,13 +351,6 @@ impl TaskHandler {
fn handle_finished_tasks(&mut self) {
let (finished, errored) = self.get_finished();

// The daemon got a reset request and all children already finished
if self.reset && self.children.is_empty() {
let mut state = self.state.lock().unwrap();
state.reset();
self.reset = false;
}

// Nothing to do. Early return
if finished.is_empty() && errored.is_empty() {
return;
Expand Down Expand Up @@ -391,7 +399,7 @@ impl TaskHandler {

// Pause the daemon, if the settings say so and some process failed
if failed_task_exists && self.pause_on_failure {
self.change_running(false);
state.running = false;
}

state.save()
Expand Down Expand Up @@ -421,6 +429,7 @@ impl TaskHandler {
}

/// Some client instructions require immediate action by the task handler
/// This function is also responsible for waiting
fn receive_commands(&mut self) {
// Sleep for a few milliseconds. We don't want to hurt the CPU.
let timeout = Duration::from_millis(100);
Expand Down Expand Up @@ -729,13 +738,6 @@ impl TaskHandler {
self.reset = true;
}

/// Change the running state consistently.
fn change_running(&mut self, running: bool) {
let mut state = self.state.lock().unwrap();
state.running = running;
state.save();
}

/// Users can specify a callback that's fired whenever a task finishes.
/// Execute the callback by spawning a new subprocess.
fn spawn_callback(&mut self, task: &Task) {
Expand Down
15 changes: 10 additions & 5 deletions shared/state.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ::anyhow::Result;
use ::chrono::prelude::*;
use ::log::{error, info};
use ::log::{error, info, debug};
use ::serde_derive::{Deserialize, Serialize};
use ::std::collections::BTreeMap;
use ::std::collections::HashMap;
Expand Down Expand Up @@ -165,10 +165,9 @@ impl State {

pub fn reset(&mut self) {
self.backup();
self.set_status_for_all_groups(true);
self.max_id = 0;
self.tasks = BTreeMap::new();
self.save();
self.set_status_for_all_groups(true);
}

/// Convenience wrapper around save_to_file.
Expand Down Expand Up @@ -207,7 +206,7 @@ impl State {
let now: DateTime<Utc> = Utc::now();
let time = now.format("%Y-%m-%d_%H-%M-%S");
(
path.join(format!("{}_backup.json.partial", time)),
path.join(format!("{}_state.json.partial", time)),
path.join(format!("{}_state.json", time)),
)
} else {
Expand All @@ -224,13 +223,19 @@ impl State {
}

// Overwrite the original with the temp file, if everything went fine.
if let Err(error) = fs::rename(&temp, real) {
if let Err(error) = fs::rename(&temp, &real) {
error!(
"Failed to overwrite old log file. File permissions? Error: {:?}",
error
);
return;
}

if log {
debug!("State backup created at: {:?}", real);
} else {
debug!("State saved at: {:?}", real);
}
}

/// Restore the last state from a previous session.
Expand Down

0 comments on commit 6c5ab4d

Please sign in to comment.