aboutsummaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorYummyOreo <bobgim20@gmail.com>2024-05-12 21:35:34 -0500
committerGitHub <noreply@github.com>2024-05-13 09:35:34 +0700
commitce67e527722cadd4ed7341a3e5d433beb62887f6 (patch)
tree41ff5ccc9d6857d1d4173a0a61f99174b644cb9e /crates
parentfix: add incremental rebuild to daemon loop (#2010) (diff)
downloadatuin-ce67e527722cadd4ed7341a3e5d433beb62887f6.zip
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 <ellie@elliehuxtable.com> * 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 <ellie@elliehuxtable.com>
Diffstat (limited to 'crates')
-rw-r--r--crates/atuin-client/config.toml15
-rw-r--r--crates/atuin-client/src/settings.rs5
-rw-r--r--crates/atuin-daemon/src/client.rs22
-rw-r--r--crates/atuin-daemon/src/server.rs62
-rw-r--r--crates/atuin/src/command/client/history.rs27
5 files changed, 107 insertions, 24 deletions
diff --git a/crates/atuin-client/config.toml b/crates/atuin-client/config.toml
index 50db6952..1de7308c 100644
--- a/crates/atuin-client/config.toml
+++ b/crates/atuin-client/config.toml
@@ -210,3 +210,18 @@ records = true
## auto: length of the selected command.
## static: length of the longest command stored in the history.
# strategy = "auto"
+
+[daemon]
+## Enables using the daemon to sync. Requires the daemon to be running in the background. Start it with `atuin daemon`
+# enabled = false
+
+## How often the daemon should sync in seconds
+# sync_frequency = 300
+
+## The path to the unix socket used by the daemon (on unix systems)
+## linux/mac: ~/.local/share/atuin/atuin.sock
+## windows: Not Supported
+# socket_path = "~/atuin.sock"
+
+## The port that should be used for TCP on non unix systems
+# tcp_port = 8889
diff --git a/crates/atuin-client/src/settings.rs b/crates/atuin-client/src/settings.rs
index ad7f95fc..ed1c0a29 100644
--- a/crates/atuin-client/src/settings.rs
+++ b/crates/atuin-client/src/settings.rs
@@ -353,6 +353,9 @@ pub struct Daemon {
/// The path to the unix socket used by the daemon
pub socket_path: String,
+
+ /// The port that should be used for TCP on non unix systems
+ pub tcp_port: u64,
}
impl Default for Preview {
@@ -369,6 +372,7 @@ impl Default for Daemon {
enabled: false,
sync_frequency: 300,
socket_path: "".to_string(),
+ tcp_port: 8889,
}
}
}
@@ -706,6 +710,7 @@ impl Settings {
.set_default("daemon.sync_frequency", 300)?
.set_default("daemon.enabled", false)?
.set_default("daemon.socket_path", socket_path.to_str())?
+ .set_default("daemon.tcp_port", 8889)?
.set_default(
"prefers_reduced_motion",
std::env::var("NO_MOTION")
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<Self> {
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<Self> {
+ 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<String> {
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
}
diff --git a/crates/atuin/src/command/client/history.rs b/crates/atuin/src/command/client/history.rs
index f966c302..9d1453fc 100644
--- a/crates/atuin/src/command/client/history.rs
+++ b/crates/atuin/src/command/client/history.rs
@@ -315,11 +315,15 @@ impl Cmd {
}
if settings.daemon.enabled {
- let resp =
- atuin_daemon::client::HistoryClient::new(settings.daemon.socket_path.clone())
- .await?
- .start_history(h)
- .await?;
+ let resp = atuin_daemon::client::HistoryClient::new(
+ #[cfg(not(unix))]
+ settings.daemon.tcp_port,
+ #[cfg(unix)]
+ settings.daemon.socket_path.clone(),
+ )
+ .await?
+ .start_history(h)
+ .await?;
// print the ID
// we use this as the key for calling end
@@ -350,10 +354,15 @@ impl Cmd {
// We will need to keep the old code around for a while.
// At the very least, while this is opt-in
if settings.daemon.enabled {
- atuin_daemon::client::HistoryClient::new(settings.daemon.socket_path.clone())
- .await?
- .end_history(id.to_string(), duration.unwrap_or(0), exit)
- .await?;
+ let resp = atuin_daemon::client::HistoryClient::new(
+ #[cfg(not(unix))]
+ settings.daemon.tcp_port,
+ #[cfg(unix)]
+ settings.daemon.socket_path.clone(),
+ )
+ .await?
+ .end_history(id.to_string(), duration.unwrap_or(0), exit)
+ .await?;
return Ok(());
}