From ce67e527722cadd4ed7341a3e5d433beb62887f6 Mon Sep 17 00:00:00 2001 From: YummyOreo Date: Sun, 12 May 2024 21:35:34 -0500 Subject: feat(daemon): add support for daemon on windows (#2014) * fix: gracefully exit on windows * feat(daemon): tcp support for windows * feat(daemon): add tcp port configuration * fix: logging and fix compiler error * docs: add build dependency to the readme fix(docs): move a line up * fix: missing field error * docs: adds the daemon section to the default config * fix: clippy and fmt * feat: Update README.md Co-authored-by: Ellie Huxtable * refactor: changes tcp port and other stuff as per request * fix(config): update default tcp port in example config * fix: complier error on unix * refactor: make the cfg stuff look better --------- Co-authored-by: Ellie Huxtable --- crates/atuin-daemon/src/client.rs | 22 +++++++++++++- crates/atuin-daemon/src/server.rs | 62 ++++++++++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 15 deletions(-) (limited to 'crates/atuin-daemon/src') diff --git a/crates/atuin-daemon/src/client.rs b/crates/atuin-daemon/src/client.rs index a832f9a9..f3fecdbc 100644 --- a/crates/atuin-daemon/src/client.rs +++ b/crates/atuin-daemon/src/client.rs @@ -1,8 +1,12 @@ use eyre::{eyre, Result}; -use tokio::net::UnixStream; +#[cfg(windows)] +use tokio::net::TcpStream; use tonic::transport::{Channel, Endpoint, Uri}; use tower::service_fn; +#[cfg(unix)] +use tokio::net::UnixStream; + use atuin_client::history::History; use crate::history::{ @@ -15,6 +19,7 @@ pub struct HistoryClient { // Wrap the grpc client impl HistoryClient { + #[cfg(unix)] pub async fn new(path: String) -> Result { let channel = Endpoint::try_from("http://atuin_local_daemon:0")? .connect_with_connector(service_fn(move |_: Uri| { @@ -30,6 +35,21 @@ impl HistoryClient { Ok(HistoryClient { client }) } + #[cfg(not(unix))] + pub async fn new(port: u64) -> Result { + let channel = Endpoint::try_from("http://atuin_local_daemon:0")? + .connect_with_connector(service_fn(move |_: Uri| { + let url = format!("127.0.0.1:{}", port); + TcpStream::connect(url) + })) + .await + .map_err(|_| eyre!("failed to connect to local atuin daemon. Is it running?"))?; + + let client = HistoryServiceClient::new(channel); + + Ok(HistoryClient { client }) + } + pub async fn start_history(&mut self, h: History) -> Result { let req = StartHistoryRequest { command: h.command, diff --git a/crates/atuin-daemon/src/server.rs b/crates/atuin-daemon/src/server.rs index 72305737..77824f60 100644 --- a/crates/atuin-daemon/src/server.rs +++ b/crates/atuin-daemon/src/server.rs @@ -13,8 +13,6 @@ use atuin_client::database::{Database, Sqlite as HistoryDatabase}; use atuin_client::history::{History, HistoryId}; use dashmap::DashMap; use eyre::Result; -use tokio::net::UnixListener; -use tokio_stream::wrappers::UnixListenerStream; use tonic::{transport::Server, Request, Response, Status}; use crate::history::history_server::{History as HistorySvc, HistoryServer}; @@ -134,6 +132,7 @@ impl HistorySvc for HistoryService { } } +#[cfg(unix)] async fn shutdown_signal(socket: PathBuf) { let mut term = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) .expect("failed to register sigterm handler"); @@ -150,6 +149,52 @@ async fn shutdown_signal(socket: PathBuf) { eprintln!("Shutting down..."); } +#[cfg(windows)] +async fn shutdown_signal() { + tokio::signal::windows::ctrl_c() + .expect("failed to register signal handler") + .recv() + .await; + eprintln!("Shutting down..."); +} + +#[cfg(unix)] +async fn start_server(settings: Settings, history: HistoryService) -> Result<()> { + use tokio::net::UnixListener; + use tokio_stream::wrappers::UnixListenerStream; + + let socket = settings.daemon.socket_path.clone(); + + let uds = UnixListener::bind(socket.clone())?; + let uds_stream = UnixListenerStream::new(uds); + + tracing::info!("listening on unix socket {:?}", socket); + Server::builder() + .add_service(HistoryServer::new(history)) + .serve_with_incoming_shutdown(uds_stream, shutdown_signal(socket.into())) + .await?; + Ok(()) +} + +#[cfg(not(unix))] +async fn start_server(settings: Settings, history: HistoryService) -> Result<()> { + use tokio::net::TcpListener; + use tokio_stream::wrappers::TcpListenerStream; + + let port = settings.daemon.tcp_port; + let url = format!("127.0.0.1:{}", port); + let tcp = TcpListener::bind(url).await?; + let tcp_stream = TcpListenerStream::new(tcp); + + tracing::info!("listening on tcp port {:?}", port); + + Server::builder() + .add_service(HistoryServer::new(history)) + .serve_with_incoming_shutdown(tcp_stream, shutdown_signal()) + .await?; + Ok(()) +} + // break the above down when we end up with multiple services /// Listen on a unix socket @@ -168,12 +213,6 @@ pub async fn listen( let history = HistoryService::new(history_store.clone(), history_db.clone()); - let socket = settings.daemon.socket_path.clone(); - let uds = UnixListener::bind(socket.clone())?; - let uds_stream = UnixListenerStream::new(uds); - - tracing::info!("listening on unix socket {:?}", socket); - // start services tokio::spawn(sync::worker( settings.clone(), @@ -182,10 +221,5 @@ pub async fn listen( history_db, )); - Server::builder() - .add_service(HistoryServer::new(history)) - .serve_with_incoming_shutdown(uds_stream, shutdown_signal(socket.into())) - .await?; - - Ok(()) + start_server(settings, history).await } -- cgit v1.3.1