feat: improved error display when startup fails
All checks were successful
Rust / build (push) Successful in 10m8s
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
Release Please / Release-plz (push) Successful in 1m8s
All checks were successful
Rust / build (push) Successful in 10m8s
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
Release Please / Release-plz (push) Successful in 1m8s
This commit is contained in:
parent
4160b6d6ee
commit
3c01a822fd
3 changed files with 61 additions and 32 deletions
|
@ -3,16 +3,17 @@ use actix::prelude::*;
|
||||||
|
|
||||||
use actix::Recipient;
|
use actix::Recipient;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use notify::event::ModifyKind;
|
use notify::{event::ModifyKind, Watcher};
|
||||||
use notify::Watcher;
|
use tracing::{error, info};
|
||||||
use tracing::error;
|
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::{
|
||||||
use std::sync::atomic::AtomicBool;
|
path::PathBuf,
|
||||||
use std::sync::atomic::Ordering;
|
sync::{
|
||||||
use std::sync::Arc;
|
atomic::{AtomicBool, Ordering},
|
||||||
use std::time::Duration;
|
Arc,
|
||||||
|
},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Message)]
|
#[derive(Debug, Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
|
@ -30,8 +31,7 @@ pub fn watch_file(path: PathBuf, recipient: Recipient<FileUpdated>) -> Result<Ar
|
||||||
let mut handler = notify::recommended_watcher(tx).context("file watcher")?;
|
let mut handler = notify::recommended_watcher(tx).context("file watcher")?;
|
||||||
handler
|
handler
|
||||||
.watch(&path, notify::RecursiveMode::NonRecursive)
|
.watch(&path, notify::RecursiveMode::NonRecursive)
|
||||||
.with_context(|| format!("Watch file: {path:?}"))?;
|
.with_context(|| format!("Watching: {path:?}"))?;
|
||||||
info!("Watching: {:?}", path);
|
|
||||||
let thread_shutdown = shutdown.clone();
|
let thread_shutdown = shutdown.clone();
|
||||||
actix_rt::task::spawn_blocking(move || {
|
actix_rt::task::spawn_blocking(move || {
|
||||||
loop {
|
loop {
|
||||||
|
@ -43,7 +43,7 @@ pub fn watch_file(path: PathBuf, recipient: Recipient<FileUpdated>) -> Result<Ar
|
||||||
match result {
|
match result {
|
||||||
Ok(event) => match event.kind {
|
Ok(event) => match event.kind {
|
||||||
notify::EventKind::Modify(ModifyKind::Data(_)) => {
|
notify::EventKind::Modify(ModifyKind::Data(_)) => {
|
||||||
tracing::info!("File modified");
|
info!("File modified");
|
||||||
recipient.do_send(FileUpdated);
|
recipient.do_send(FileUpdated);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,24 +53,25 @@ fn main() -> Result<()> {
|
||||||
let commands = Commands::parse();
|
let commands = Commands::parse();
|
||||||
|
|
||||||
match commands.command {
|
match commands.command {
|
||||||
Command::Init => {
|
Command::Init => init::run(&fs),
|
||||||
init::run(&fs)?;
|
|
||||||
}
|
|
||||||
Command::Server(server) => match server {
|
Command::Server(server) => match server {
|
||||||
Server::Init => {
|
Server::Init => server::init(&fs),
|
||||||
server::init(&fs)?;
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "tui"))]
|
#[cfg(not(feature = "tui"))]
|
||||||
Server::Start {} => {
|
Server::Start {} => server::start(
|
||||||
let sleep_duration = std::time::Duration::from_secs(10);
|
false,
|
||||||
server::start(false, fs, net, repository_factory, sleep_duration)?;
|
fs,
|
||||||
}
|
net,
|
||||||
|
repository_factory,
|
||||||
|
std::time::Duration::from_secs(10),
|
||||||
|
),
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
Server::Start { ui } => {
|
Server::Start { ui } => server::start(
|
||||||
let sleep_duration = std::time::Duration::from_secs(10);
|
ui,
|
||||||
server::start(ui, fs, net, repository_factory, sleep_duration)?;
|
fs,
|
||||||
}
|
net,
|
||||||
|
repository_factory,
|
||||||
|
std::time::Duration::from_secs(10),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,13 @@ use git_next_core::git::RepositoryFactory;
|
||||||
|
|
||||||
use color_eyre::{eyre::Context, Result};
|
use color_eyre::{eyre::Context, Result};
|
||||||
use kxio::{fs::FileSystem, network::Network};
|
use kxio::{fs::FileSystem, network::Network};
|
||||||
use tracing::info;
|
use tracing::{error, info};
|
||||||
|
|
||||||
use std::{path::PathBuf, sync::atomic::Ordering, time::Duration};
|
use std::{
|
||||||
|
path::PathBuf,
|
||||||
|
sync::{atomic::Ordering, Arc, RwLock},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
const A_DAY: Duration = Duration::from_secs(24 * 60 * 60);
|
const A_DAY: Duration = Duration::from_secs(24 * 60 * 60);
|
||||||
|
|
||||||
|
@ -57,6 +61,8 @@ pub fn start(
|
||||||
init_logging();
|
init_logging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let file_watcher_err_channel: Arc<RwLock<Option<anyhow::Error>>> = Arc::new(RwLock::new(None));
|
||||||
|
let file_watcher_err_channel_exec = file_watcher_err_channel.clone();
|
||||||
let execution = async move {
|
let execution = async move {
|
||||||
info!("Starting Alert Dispatcher...");
|
info!("Starting Alert Dispatcher...");
|
||||||
let alerts_addr = AlertsActor::new(None, History::new(A_DAY), net.clone()).start();
|
let alerts_addr = AlertsActor::new(None, History::new(A_DAY), net.clone()).start();
|
||||||
|
@ -66,9 +72,20 @@ pub fn start(
|
||||||
ServerActor::new(fs.clone(), net.clone(), alerts_addr, repo, sleep_duration).start();
|
ServerActor::new(fs.clone(), net.clone(), alerts_addr, repo, sleep_duration).start();
|
||||||
|
|
||||||
info!("Starting File Watcher...");
|
info!("Starting File Watcher...");
|
||||||
#[allow(clippy::expect_used)]
|
let watch_file = watch_file("git-next-server.toml".into(), server.clone().recipient());
|
||||||
let fw_shutdown = watch_file("git-next-server.toml".into(), server.clone().recipient())
|
let fw_shutdown = match watch_file {
|
||||||
.expect("file watcher");
|
Ok(fw_shutdown) => fw_shutdown,
|
||||||
|
Err(err) => {
|
||||||
|
// shutdown now
|
||||||
|
server.do_send(crate::server::actor::messages::Shutdown);
|
||||||
|
actix_rt::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||||
|
System::current().stop();
|
||||||
|
let _ = file_watcher_err_channel_exec
|
||||||
|
.write()
|
||||||
|
.map(|mut o| o.replace(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if ui {
|
if ui {
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
|
@ -106,6 +123,17 @@ pub fn start(
|
||||||
let system = System::new();
|
let system = System::new();
|
||||||
Arbiter::current().spawn(execution);
|
Arbiter::current().spawn(execution);
|
||||||
system.run()?;
|
system.run()?;
|
||||||
|
|
||||||
|
// check for error from file watcher thread
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
if let Some(err) = &*file_watcher_err_channel.read().unwrap() {
|
||||||
|
if ui {
|
||||||
|
eprintln!("File Watcher: {err:?}");
|
||||||
|
}
|
||||||
|
error!(?err, "file watcher");
|
||||||
|
return Err(color_eyre::eyre::eyre!(format!("{err}")));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue