aboutsummaryrefslogtreecommitdiff
path: root/src/output_protocol/ipc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/output_protocol/ipc.rs')
-rw-r--r--src/output_protocol/ipc.rs68
1 files changed, 62 insertions, 6 deletions
diff --git a/src/output_protocol/ipc.rs b/src/output_protocol/ipc.rs
index c9c88c1..fb6df80 100644
--- a/src/output_protocol/ipc.rs
+++ b/src/output_protocol/ipc.rs
@@ -1,14 +1,70 @@
use crate::OutputProtocol;
+use crate::debug_log;
+use std::path::PathBuf;
+use std::sync::Arc;
+use tokio::io::AsyncWriteExt;
+use tokio::net::UnixStream;
-#[derive(Debug, Default)]
-pub struct IPCOutputProtocol {}
+/// IPC output protocol.
+///
+/// Connects to a Unix domain socket and sends messages to it.
+/// On Windows, this will fail with a clear error message since
+/// Unix domain sockets are not supported.
+#[derive(Debug)]
+pub struct IPCOutputProtocol {
+ socket_path: PathBuf,
+ stream: tokio::sync::Mutex<Option<UnixStream>>,
+}
+
+impl IPCOutputProtocol {
+ pub fn new(socket_path: PathBuf) -> Self {
+ Self {
+ socket_path,
+ stream: tokio::sync::Mutex::new(None),
+ }
+ }
+}
impl OutputProtocol for IPCOutputProtocol {
- async fn init(self) {
- todo!()
+ async fn init(&self) {
+ let path = self.socket_path.clone();
+ let stream_lock = &self.stream;
+
+ match UnixStream::connect(&path).await {
+ Ok(stream) => {
+ debug_log!("[IPC] Connected to {}", path.display());
+ *stream_lock.lock().await = Some(stream);
+ }
+ Err(e) => {
+ debug_log!("[IPC] Failed to connect to {}: {}", path.display(), e);
+ }
+ }
}
- async fn send(self: std::sync::Arc<Self>, _str: &str) {
- todo!()
+ async fn send(self: Arc<Self>, message: &str) {
+ let mut guard = self.stream.lock().await;
+ if let Some(ref mut stream) = *guard {
+ let bytes = format!("{}\n", message);
+ if stream.write_all(bytes.as_bytes()).await.is_err() {
+ debug_log!("[IPC] Write error, reconnecting...");
+ *guard = None;
+ // Try to reconnect
+ if let Ok(new_stream) = UnixStream::connect(&self.socket_path).await {
+ debug_log!("[IPC] Reconnected to {}", self.socket_path.display());
+ *guard = Some(new_stream);
+ }
+ }
+ } else {
+ // Try to connect
+ if let Ok(stream) = UnixStream::connect(&self.socket_path).await {
+ debug_log!("[IPC] Connected to {}", self.socket_path.display());
+ let bytes = format!("{}\n", message);
+ let _ = stream.writable().await;
+ // We can't use the stream directly here since we need to store it
+ // for future sends. Let's store and send.
+ let _ = stream.try_write(bytes.as_bytes());
+ *guard = Some(stream);
+ }
+ }
}
}