From c1bcfb93563a7d927bda04d885359564b5c273cc Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Tue, 6 Feb 2024 11:24:03 -0500 Subject: [PATCH 1/2] Provided a fallback for restart to clean --- crates/turborepo-lib/src/commands/daemon.rs | 90 +++++++++++++-------- crates/turborepo-lib/src/lib.rs | 1 + 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/crates/turborepo-lib/src/commands/daemon.rs b/crates/turborepo-lib/src/commands/daemon.rs index 7c06a4f7d3b3c..9bf2f73525a92 100644 --- a/crates/turborepo-lib/src/commands/daemon.rs +++ b/crates/turborepo-lib/src/commands/daemon.rs @@ -6,7 +6,7 @@ use pidlock::PidlockError::AlreadyOwned; use time::{format_description, OffsetDateTime}; use tokio::signal::ctrl_c; use tracing::{trace, warn}; -use turbopath::AbsoluteSystemPathBuf; +use turbopath::{AbsoluteSystemPath, AbsoluteSystemPathBuf}; use super::CommandBase; use crate::{ @@ -19,11 +19,14 @@ use crate::{ pub async fn daemon_client(command: &DaemonCommand, base: &CommandBase) -> Result<(), DaemonError> { let (can_start_server, can_kill_server) = match command { DaemonCommand::Status { .. } => (false, false), - DaemonCommand::Restart | DaemonCommand::Stop => (false, true), - DaemonCommand::Start => (true, true), + DaemonCommand::Stop => (false, true), + DaemonCommand::Restart | DaemonCommand::Start => (true, true), DaemonCommand::Clean => (false, true), }; + println!("can_start_server: {}", can_start_server); + println!("can_kill_server: {}", can_kill_server); + let pid_file = base.daemon_file_root().join_component("turbod.pid"); let sock_file = base.daemon_file_root().join_component("turbod.sock"); @@ -36,8 +39,18 @@ pub async fn daemon_client(command: &DaemonCommand, base: &CommandBase) -> Resul match command { DaemonCommand::Restart => { - let client = connector.connect().await?; - client.restart().await?; + let result: Result<_, DaemonError> = try { + let client = connector.clone().connect().await?; + client.restart().await? + }; + + if let Err(e) = result { + println!("failed to restart the daemon: {:?}", e); + println!("falling back to clean"); + clean(&pid_file, &sock_file).await?; + println!("connecting for second time"); + let _ = connector.connect().await?; + } } DaemonCommand::Start => { // We don't care about the client, but we do care that we can connect @@ -87,42 +100,49 @@ pub async fn daemon_client(command: &DaemonCommand, base: &CommandBase) -> Resul tracing::trace!("unable to connect to the daemon: {:?}", e); } } - - // remove pid and sock files - let mut success = true; - trace!("cleaning up daemon files"); - // if the pid_file and sock_file still exist, remove them: - if pid_file.exists() { - let result = std::fs::remove_file(pid_file.clone()); - // ignore this error - if let Err(e) = result { - println!("Failed to remove pid file: {}", e); - println!("Please remove manually: {}", pid_file); - success = false; - } - } - if sock_file.exists() { - let result = std::fs::remove_file(sock_file.clone()); - // ignore this error - if let Err(e) = result { - println!("Failed to remove socket file: {}", e); - println!("Please remove manually: {}", sock_file); - success = false; - } - } - - if success { - println!("Done"); - } else { - // return error - return Err(DaemonError::CleanFailed); - } + clean(&pid_file, &sock_file).await?; } }; Ok(()) } +async fn clean( + pid_file: &AbsoluteSystemPath, + sock_file: &AbsoluteSystemPath, +) -> Result<(), DaemonError> { + // remove pid and sock files + let mut success = true; + trace!("cleaning up daemon files"); + // if the pid_file and sock_file still exist, remove them: + if pid_file.exists() { + let result = std::fs::remove_file(pid_file); + // ignore this error + if let Err(e) = result { + println!("Failed to remove pid file: {}", e); + println!("Please remove manually: {}", pid_file); + success = false; + } + } + if sock_file.exists() { + let result = std::fs::remove_file(sock_file); + // ignore this error + if let Err(e) = result { + println!("Failed to remove socket file: {}", e); + println!("Please remove manually: {}", sock_file); + success = false; + } + } + + if success { + println!("Done"); + Ok(()) + } else { + // return error + Err(DaemonError::CleanFailed) + } +} + // log_filename matches the algorithm used by tracing_appender::Rotation::DAILY // to generate the log filename. This is kind of a hack, but there didn't appear // to be a simple way to grab the generated filename. diff --git a/crates/turborepo-lib/src/lib.rs b/crates/turborepo-lib/src/lib.rs index 8a4c3b3f91bc3..54eb888197398 100644 --- a/crates/turborepo-lib/src/lib.rs +++ b/crates/turborepo-lib/src/lib.rs @@ -5,6 +5,7 @@ #![feature(hash_extract_if)] #![feature(option_get_or_insert_default)] #![feature(once_cell_try)] +#![feature(try_blocks)] #![deny(clippy::all)] // Clippy's needless mut lint is buggy: https://github.com/rust-lang/rust-clippy/issues/11299 #![allow(clippy::needless_pass_by_ref_mut)] From cc44cfaaa7f54b4777aca2dfa82785c92acd6bdb Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Tue, 6 Feb 2024 11:29:04 -0500 Subject: [PATCH 2/2] Fixed daemon restart --- crates/turborepo-lib/src/commands/daemon.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/turborepo-lib/src/commands/daemon.rs b/crates/turborepo-lib/src/commands/daemon.rs index 9bf2f73525a92..37a07104ceca5 100644 --- a/crates/turborepo-lib/src/commands/daemon.rs +++ b/crates/turborepo-lib/src/commands/daemon.rs @@ -24,9 +24,6 @@ pub async fn daemon_client(command: &DaemonCommand, base: &CommandBase) -> Resul DaemonCommand::Clean => (false, true), }; - println!("can_start_server: {}", can_start_server); - println!("can_kill_server: {}", can_kill_server); - let pid_file = base.daemon_file_root().join_component("turbod.pid"); let sock_file = base.daemon_file_root().join_component("turbod.sock"); @@ -45,12 +42,14 @@ pub async fn daemon_client(command: &DaemonCommand, base: &CommandBase) -> Resul }; if let Err(e) = result { - println!("failed to restart the daemon: {:?}", e); - println!("falling back to clean"); + tracing::debug!("failed to restart the daemon: {:?}", e); + tracing::debug!("falling back to clean"); clean(&pid_file, &sock_file).await?; - println!("connecting for second time"); + tracing::debug!("connecting for second time"); let _ = connector.connect().await?; } + + println!("restarted daemon"); } DaemonCommand::Start => { // We don't care about the client, but we do care that we can connect @@ -101,6 +100,7 @@ pub async fn daemon_client(command: &DaemonCommand, base: &CommandBase) -> Resul } } clean(&pid_file, &sock_file).await?; + println!("Done"); } }; @@ -135,7 +135,6 @@ async fn clean( } if success { - println!("Done"); Ok(()) } else { // return error