refactor(m1): restructure watcher into module with EventSource, SystemEvent
Replace flat watcher.rs with watcher/ module containing mod.rs plus stub sub-modules for journald, kmsg, and inotify. Upgrades spawn() to accept log_paths and return mpsc::Receiver<SystemEvent>. Updates lib.rs call site.
This commit is contained in:
parent
6acf085c0f
commit
d1bea47495
6 changed files with 105 additions and 39 deletions
|
|
@ -24,7 +24,7 @@ pub fn run() {
|
|||
})
|
||||
.setup(|app| {
|
||||
tray::build_tray(&app.handle())?;
|
||||
watcher::spawn();
|
||||
watcher::spawn(std::collections::HashMap::new());
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
/// System event watcher — M1 implementation.
|
||||
///
|
||||
/// M0 stub: defines the types and the spawn interface so the rest of the app
|
||||
/// can wire up event handling now. Actual journald/dmesg reading lands in M1.
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EventSeverity {
|
||||
Info,
|
||||
Warn,
|
||||
Crit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum EventSource {
|
||||
Journald,
|
||||
Kmsg,
|
||||
AppLog { app: String },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SystemEvent {
|
||||
pub source: EventSource,
|
||||
pub raw_line: String,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
/// Starts the background watcher task.
|
||||
/// M0: no-op placeholder — returns immediately.
|
||||
/// M1: spawns a tokio task reading journald + dmesg and emitting events.
|
||||
pub fn spawn() {
|
||||
// TODO(M1): spawn tokio::task reading journald via sd-journal crate
|
||||
// TODO(M1): spawn dmesg poller for kernel messages
|
||||
// TODO(M1): emit SystemEvent via tauri app_handle.emit()
|
||||
log::info!("watcher: stub — no-op until M1");
|
||||
}
|
||||
7
src-tauri/src/watcher/inotify.rs
Normal file
7
src-tauri/src/watcher/inotify.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
use super::SystemEvent;
|
||||
use std::collections::HashMap;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
pub async fn watch(_log_paths: HashMap<String, String>, _tx: mpsc::Sender<SystemEvent>) {
|
||||
// implemented in Task 8
|
||||
}
|
||||
6
src-tauri/src/watcher/journald.rs
Normal file
6
src-tauri/src/watcher/journald.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
use super::SystemEvent;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
pub async fn watch(_tx: mpsc::Sender<SystemEvent>) {
|
||||
// implemented in Task 6
|
||||
}
|
||||
6
src-tauri/src/watcher/kmsg.rs
Normal file
6
src-tauri/src/watcher/kmsg.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
use super::SystemEvent;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
pub async fn watch(_tx: mpsc::Sender<SystemEvent>) {
|
||||
// implemented in Task 7
|
||||
}
|
||||
85
src-tauri/src/watcher/mod.rs
Normal file
85
src-tauri/src/watcher/mod.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
pub mod inotify;
|
||||
pub mod journald;
|
||||
pub mod kmsg;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EventSeverity {
|
||||
Info,
|
||||
Warn,
|
||||
Crit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum EventSource {
|
||||
Journald,
|
||||
Kmsg,
|
||||
AppLog { app: String },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SystemEvent {
|
||||
pub source: EventSource,
|
||||
pub raw_line: String,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
pub fn now_unix() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs()
|
||||
}
|
||||
|
||||
/// Spawns all watcher tasks. Returns the receiver end of the event channel.
|
||||
/// `log_paths` comes from the loaded PatternFile.
|
||||
pub fn spawn(log_paths: HashMap<String, String>) -> mpsc::Receiver<SystemEvent> {
|
||||
let (tx, rx) = mpsc::channel::<SystemEvent>(256);
|
||||
|
||||
let tx_j = tx.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
journald::watch(tx_j).await;
|
||||
});
|
||||
|
||||
let tx_k = tx.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
kmsg::watch(tx_k).await;
|
||||
});
|
||||
|
||||
tauri::async_runtime::spawn(async move {
|
||||
inotify::watch(log_paths, tx).await;
|
||||
});
|
||||
|
||||
rx
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn event_source_can_be_cloned() {
|
||||
let s = EventSource::AppLog {
|
||||
app: "steam".into(),
|
||||
};
|
||||
let _ = s.clone();
|
||||
assert!(matches!(s, EventSource::AppLog { .. }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn system_event_constructed() {
|
||||
let e = SystemEvent {
|
||||
source: EventSource::Journald,
|
||||
raw_line: "test line".into(),
|
||||
timestamp: now_unix(),
|
||||
};
|
||||
assert_eq!(e.raw_line, "test line");
|
||||
assert!(e.timestamp > 0);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue