feat(core): improve troubleshooter behavior on critical errors
This commit is contained in:
parent
6dc3f1093d
commit
925a411460
|
@ -90,20 +90,26 @@ fn daemon_main(args: CliModuleArgs) -> i32 {
|
||||||
// at a given time.
|
// at a given time.
|
||||||
let mut _current_troubleshoot_guard = None;
|
let mut _current_troubleshoot_guard = None;
|
||||||
|
|
||||||
let config_store = match troubleshoot::load_config_or_troubleshoot(&paths, &paths_overrides) {
|
let (watcher_notify, watcher_signal) = unbounded::<()>();
|
||||||
troubleshoot::LoadResult::Correct(load_result) => load_result.config_store,
|
|
||||||
troubleshoot::LoadResult::Warning(load_result, guard) => {
|
watcher::initialize_and_spawn(&paths.config, watcher_notify)
|
||||||
_current_troubleshoot_guard = guard;
|
.expect("unable to initialize config watcher thread");
|
||||||
load_result.config_store
|
|
||||||
}
|
let config_store =
|
||||||
troubleshoot::LoadResult::Fatal(mut guard) => {
|
match troubleshoot::load_config_or_troubleshoot_until_config_is_correct_or_abort(
|
||||||
guard
|
&paths,
|
||||||
.wait()
|
&paths_overrides,
|
||||||
.expect("unable to wait for troubleshooting guard");
|
watcher_signal.clone(),
|
||||||
error!("critical error while loading config");
|
) {
|
||||||
return DAEMON_FATAL_CONFIG_ERROR;
|
Ok((result, guard)) => {
|
||||||
}
|
_current_troubleshoot_guard = guard;
|
||||||
};
|
result.config_store
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("critical error while loading config: {}", err);
|
||||||
|
return DAEMON_FATAL_CONFIG_ERROR;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
info!("espanso version: {}", VERSION);
|
info!("espanso version: {}", VERSION);
|
||||||
// TODO: print os system and version? (with os_info crate)
|
// TODO: print os system and version? (with os_info crate)
|
||||||
|
@ -126,13 +132,6 @@ fn daemon_main(args: CliModuleArgs) -> i32 {
|
||||||
ipc::initialize_and_spawn(&paths.runtime, exit_notify.clone())
|
ipc::initialize_and_spawn(&paths.runtime, exit_notify.clone())
|
||||||
.expect("unable to initialize ipc server for daemon");
|
.expect("unable to initialize ipc server for daemon");
|
||||||
|
|
||||||
let (watcher_notify, watcher_signal) = unbounded::<()>();
|
|
||||||
|
|
||||||
if config_store.default().auto_restart() {
|
|
||||||
watcher::initialize_and_spawn(&paths.config, watcher_notify)
|
|
||||||
.expect("unable to initialize config watcher thread");
|
|
||||||
}
|
|
||||||
|
|
||||||
if cli_args.is_present("show-welcome") {
|
if cli_args.is_present("show-welcome") {
|
||||||
ui::show_welcome_screen(&preferences);
|
ui::show_welcome_screen(&preferences);
|
||||||
}
|
}
|
||||||
|
@ -140,6 +139,10 @@ fn daemon_main(args: CliModuleArgs) -> i32 {
|
||||||
loop {
|
loop {
|
||||||
select! {
|
select! {
|
||||||
recv(watcher_signal) -> _ => {
|
recv(watcher_signal) -> _ => {
|
||||||
|
if !config_store.default().auto_restart() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
info!("configuration change detected, restarting worker process...");
|
info!("configuration change detected, restarting worker process...");
|
||||||
|
|
||||||
// Before killing the previous worker, we make sure there is no fatal error
|
// Before killing the previous worker, we make sure there is no fatal error
|
||||||
|
|
|
@ -18,9 +18,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::process::{Child, Command};
|
use std::process::{Child, Command};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::{Result};
|
use anyhow::{bail, Result};
|
||||||
|
use crossbeam::channel::Receiver;
|
||||||
|
use crossbeam::select;
|
||||||
use espanso_path::Paths;
|
use espanso_path::Paths;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
use crate::cli::util::CommandExt;
|
use crate::cli::util::CommandExt;
|
||||||
use crate::cli::PathsOverrides;
|
use crate::cli::PathsOverrides;
|
||||||
|
@ -47,10 +51,15 @@ impl TroubleshootGuard {
|
||||||
pub fn new(child: Child) -> Self {
|
pub fn new(child: Child) -> Self {
|
||||||
Self { child }
|
Self { child }
|
||||||
}
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn wait(&mut self) -> Result<()> {
|
pub fn wait(&mut self) -> Result<()> {
|
||||||
self.child.wait()?;
|
self.child.wait()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub fn try_wait(&mut self) -> Result<bool> {
|
||||||
|
let result = self.child.try_wait()?;
|
||||||
|
Ok(result.is_some())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for TroubleshootGuard {
|
impl Drop for TroubleshootGuard {
|
||||||
|
@ -97,3 +106,44 @@ pub fn load_config_or_troubleshoot(paths: &Paths, paths_overrides: &PathsOverrid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_config_or_troubleshoot_until_config_is_correct_or_abort(
|
||||||
|
paths: &Paths,
|
||||||
|
paths_overrides: &PathsOverrides,
|
||||||
|
watcher_receiver: Receiver<()>,
|
||||||
|
) -> Result<(ConfigLoadResult, Option<TroubleshootGuard>)> {
|
||||||
|
let mut _troubleshoot_guard = None;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// If the loading process is fatal, we keep showing the troubleshooter until
|
||||||
|
// either the config is correct or the user aborts by closing the troubleshooter
|
||||||
|
_troubleshoot_guard = match load_config_or_troubleshoot(paths, paths_overrides) {
|
||||||
|
LoadResult::Correct(result) => return Ok((result, None)),
|
||||||
|
LoadResult::Warning(result, guard) => return Ok((result, guard)),
|
||||||
|
LoadResult::Fatal(guard) => Some(guard),
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
select! {
|
||||||
|
recv(watcher_receiver) -> _ => {
|
||||||
|
info!("config change detected, reloading configs...");
|
||||||
|
|
||||||
|
break
|
||||||
|
},
|
||||||
|
default(Duration::from_millis(500)) => {
|
||||||
|
if let Some(guard) = &mut _troubleshoot_guard {
|
||||||
|
if let Ok(ended) = guard.try_wait() {
|
||||||
|
if ended {
|
||||||
|
bail!("user aborted troubleshooter");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bail!("unable to wait for troubleshooter");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bail!("no troubleshoot guard found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user