Make daemon startup explicit
This commit is contained in:
parent
84cce399d0
commit
018bfee24c
4 changed files with 47 additions and 66 deletions
|
@ -20,7 +20,7 @@ pub fn handle_client_only_action(action: ActionClientOnly) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn forward_command_to_server(mut stream: UnixStream, action: opts::ActionWithServer) -> Result<()> {
|
||||
pub fn do_server_call(mut stream: UnixStream, action: opts::ActionWithServer) -> Result<Option<String>> {
|
||||
log::info!("Forwarding options to server");
|
||||
stream
|
||||
.set_nonblocking(false)
|
||||
|
@ -43,8 +43,6 @@ pub fn forward_command_to_server(mut stream: UnixStream, action: opts::ActionWit
|
|||
stream
|
||||
.read_to_string(&mut buf)
|
||||
.context("Error reading response from server")?;
|
||||
if !buf.is_empty() {
|
||||
println!("{}", buf);
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Ok(if buf.is_empty() { None } else { Some(buf) })
|
||||
}
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -53,16 +53,31 @@ fn main() {
|
|||
}
|
||||
opts::Action::WithServer(action) => {
|
||||
log::info!("Trying to find server process");
|
||||
if let Some(stream) = try_connect(&*IPC_SOCKET_PATH) {
|
||||
log::info!("Connected to eww server.");
|
||||
client::forward_command_to_server(stream, action).context("Error while forwarding command to server")?;
|
||||
} else if action.needs_server_running() {
|
||||
println!("No eww server running");
|
||||
match net::UnixStream::connect(&*IPC_SOCKET_PATH) {
|
||||
Ok(stream) => {
|
||||
log::info!("Connected to Eww server.");
|
||||
let response =
|
||||
client::do_server_call(stream, action).context("Error while forwarding command to server")?;
|
||||
if let Some(response) = response {
|
||||
println!("{}", response);
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
println!("Failed to connect to the eww daemon.");
|
||||
println!("Make sure to start the eww daemon process by running `eww daemon` first.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opts::Action::Daemon => {
|
||||
// make sure that there isn't already a Eww daemon running.
|
||||
if check_server_running(&*IPC_SOCKET_PATH) {
|
||||
eprintln!("Eww server already running.");
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
log::info!("No server running, initializing server...");
|
||||
log::info!("Initializing Eww server.");
|
||||
let _ = std::fs::remove_file(&*crate::IPC_SOCKET_PATH);
|
||||
server::initialize_server(opts.should_detach, action)?;
|
||||
server::initialize_server()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,16 +85,14 @@ fn main() {
|
|||
|
||||
if let Err(e) = result {
|
||||
eprintln!("{:?}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn try_connect(path: &std::path::PathBuf) -> Option<net::UnixStream> {
|
||||
if path.exists() {
|
||||
for _ in 0..5 {
|
||||
if let Ok(stream) = net::UnixStream::connect(&*IPC_SOCKET_PATH) {
|
||||
return Some(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
/// Check if a eww server is currently running by trying to send a ping message to it.
|
||||
fn check_server_running(socket_path: &std::path::PathBuf) -> bool {
|
||||
let response = net::UnixStream::connect(socket_path)
|
||||
.ok()
|
||||
.and_then(|stream| client::do_server_call(stream, opts::ActionWithServer::Ping).ok());
|
||||
response.is_some()
|
||||
}
|
||||
|
|
28
src/opts.rs
28
src/opts.rs
|
@ -11,7 +11,6 @@ use crate::{
|
|||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct Opt {
|
||||
pub action: Action,
|
||||
pub should_detach: bool,
|
||||
}
|
||||
|
||||
/// Helper struct that will be normalized into instance of [Opt]
|
||||
|
@ -23,6 +22,10 @@ struct RawOpt {
|
|||
|
||||
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub enum Action {
|
||||
/// Start the Eww daemon.
|
||||
#[structopt(name = "daemon")]
|
||||
Daemon,
|
||||
|
||||
#[structopt(flatten)]
|
||||
ClientOnly(ActionClientOnly),
|
||||
|
||||
|
@ -39,10 +42,6 @@ pub enum ActionClientOnly {
|
|||
|
||||
#[derive(StructOpt, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub enum ActionWithServer {
|
||||
/// Start the eww daemon.
|
||||
#[structopt(name = "daemon")]
|
||||
Daemon,
|
||||
|
||||
/// Ping the eww server, checking if it is reachable.
|
||||
#[structopt(name = "ping")]
|
||||
Ping,
|
||||
|
@ -113,10 +112,7 @@ impl Opt {
|
|||
impl From<RawOpt> for Opt {
|
||||
fn from(other: RawOpt) -> Self {
|
||||
let RawOpt { action } = other;
|
||||
Opt {
|
||||
should_detach: action == Action::WithServer(ActionWithServer::Daemon),
|
||||
action,
|
||||
}
|
||||
Opt { action }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +126,11 @@ fn parse_var_update_arg(s: &str) -> Result<(VarName, PrimitiveValue)> {
|
|||
impl ActionWithServer {
|
||||
pub fn into_eww_command(self) -> (app::EwwCommand, Option<tokio::sync::mpsc::UnboundedReceiver<String>>) {
|
||||
let command = match self {
|
||||
ActionWithServer::Daemon | ActionWithServer::Ping => app::EwwCommand::NoOp,
|
||||
ActionWithServer::Ping => {
|
||||
let (send, recv) = tokio::sync::mpsc::unbounded_channel();
|
||||
let _ = send.send("pong".to_owned());
|
||||
return (app::EwwCommand::NoOp, Some(recv));
|
||||
}
|
||||
ActionWithServer::Update { mappings } => app::EwwCommand::UpdateVars(mappings.into_iter().collect()),
|
||||
ActionWithServer::OpenMany { windows } => app::EwwCommand::OpenMany(windows),
|
||||
ActionWithServer::OpenWindow {
|
||||
|
@ -158,12 +158,4 @@ impl ActionWithServer {
|
|||
};
|
||||
(command, None)
|
||||
}
|
||||
|
||||
/// returns true if this command requires a server to already be running
|
||||
pub fn needs_server_running(&self) -> bool {
|
||||
match self {
|
||||
ActionWithServer::OpenWindow { .. } | ActionWithServer::Daemon => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,8 @@ use tokio::{
|
|||
sync::mpsc::*,
|
||||
};
|
||||
|
||||
pub fn initialize_server(should_detach: bool, action: opts::ActionWithServer) -> Result<()> {
|
||||
if should_detach {
|
||||
do_detach()?;
|
||||
}
|
||||
pub fn initialize_server() -> Result<()> {
|
||||
do_detach()?;
|
||||
|
||||
simple_signal::set_handler(&[simple_signal::Signal::Int, simple_signal::Signal::Term], move |_| {
|
||||
println!("Shutting down eww daemon...");
|
||||
|
@ -24,6 +22,7 @@ pub fn initialize_server(should_detach: bool, action: opts::ActionWithServer) ->
|
|||
std::process::exit(1);
|
||||
}
|
||||
});
|
||||
let (ui_send, mut ui_recv) = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
let config_file_path = crate::CONFIG_DIR.join("eww.xml");
|
||||
let config_dir = config_file_path
|
||||
|
@ -36,7 +35,6 @@ pub fn initialize_server(should_detach: bool, action: opts::ActionWithServer) ->
|
|||
let eww_config = config::EwwConfig::read_from_file(&config_file_path)?;
|
||||
|
||||
gtk::init()?;
|
||||
let (ui_send, mut ui_recv) = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
log::info!("Initializing script var handler");
|
||||
let script_var_handler = script_var_handler::init(ui_send.clone());
|
||||
|
@ -58,13 +56,8 @@ pub fn initialize_server(should_detach: bool, action: opts::ActionWithServer) ->
|
|||
app.load_css(&eww_css)?;
|
||||
}
|
||||
|
||||
// run the command that eww was started with
|
||||
log::info!("running command: {:?}", &action);
|
||||
let (command, maybe_response_recv) = action.into_eww_command();
|
||||
app.handle_command(command);
|
||||
|
||||
// initialize all the handlers and tasks running asyncronously
|
||||
init_async_part(config_file_path, scss_file_path, maybe_response_recv, ui_send);
|
||||
init_async_part(config_file_path, scss_file_path, ui_send);
|
||||
|
||||
glib::MainContext::default().spawn_local(async move {
|
||||
while let Some(event) = ui_recv.recv().await {
|
||||
|
@ -78,28 +71,13 @@ pub fn initialize_server(should_detach: bool, action: opts::ActionWithServer) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn init_async_part(
|
||||
config_file_path: PathBuf,
|
||||
scss_file_path: PathBuf,
|
||||
maybe_response_recv: Option<UnboundedReceiver<String>>,
|
||||
ui_send: UnboundedSender<app::EwwCommand>,
|
||||
) {
|
||||
fn init_async_part(config_file_path: PathBuf, scss_file_path: PathBuf, ui_send: UnboundedSender<app::EwwCommand>) {
|
||||
std::thread::spawn(move || {
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("Failed to initialize tokio runtime");
|
||||
rt.block_on(async {
|
||||
// TODO This really does not belong here at all :<
|
||||
// print out the response of this initial command, if there is any
|
||||
tokio::spawn(async {
|
||||
if let Some(mut response_recv) = maybe_response_recv {
|
||||
if let Ok(Some(response)) = tokio::time::timeout(Duration::from_millis(100), response_recv.recv()).await {
|
||||
println!("{}", response);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let filewatch_join_handle = {
|
||||
let ui_send = ui_send.clone();
|
||||
tokio::spawn(async move { run_filewatch(config_file_path, scss_file_path, ui_send).await })
|
||||
|
|
Loading…
Add table
Reference in a new issue