Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2572168
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/Cargo.toml b/Cargo.toml
index 43fc476..e5a5731 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,15 +1,15 @@
[package]
name = "pawd"
-version = "0.1.0"
+version = "0.1.1"
edition = "2021"
license = "MIT"
repository = "https://lab.themackabu.dev/crates/pawd"
description = "Process analysis & watcher daemon"
[dependencies]
+serde_json = "1.0.108"
psutil = { version = "3.2.2", features = ["serde"] }
-serde = "1.0.192"
-serde_derive = "1.0.192"
+serde = { version = "1.0.192", features = ["derive"] }
[dev-dependencies]
-assert_matches = "1.5.0"
\ No newline at end of file
+assert_matches = "1.5.0"
diff --git a/src/lib.rs b/src/lib.rs
index 08a4f2e..611890c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,110 +1,118 @@
mod structs;
use psutil::process::{MemoryInfo, Process};
use std::io::{self, Read};
use std::process::{Command, Stdio};
use std::thread::{sleep, spawn};
use std::time::{Duration, Instant};
use structs::{PawDone, PawInfo, PawProcess, PawResult};
/// Represents a process watcher that monitors the resource usage of a child process.
#[derive(Debug, Clone)]
pub struct Paw {
command: String,
arguments: Vec<String>,
duration: Duration,
}
impl Paw {
/// Creates a new `Paw` instance with the specified command, arguments, and duration.
pub fn new<T: AsRef<str>>(command: &str, arguments: &[T], duration: u64) -> Paw {
Paw {
command: command.to_string(),
arguments: arguments.iter().map(|s| s.as_ref().to_string()).collect(),
duration: Duration::from_millis(duration),
}
}
/// Watches the process and calls the provided callback with the result at regular intervals.
///
/// # Arguments
///
/// * `callback` - A callback function that takes a `PawResult` as its parameter.
///
/// # Returns
///
/// Returns a `Result` containing a `PawDone` indicating the completion status.
pub fn watch<F: Fn(PawResult) + Send + 'static>(&self, callback: F) -> Result<PawDone, Box<dyn std::error::Error>> {
let mut child = Command::new(&self.command).args(&self.arguments).stdout(Stdio::piped()).spawn()?;
let done: PawDone;
let pid = child.id();
let start_time = Instant::now();
let stdout_handle = child.stdout.take().unwrap();
let stdout_thread = spawn(move || {
let mut buffer = String::new();
let mut reader = io::BufReader::new(stdout_handle);
reader.read_to_string(&mut buffer).unwrap();
buffer
});
loop {
let uptime = start_time.elapsed().as_millis();
let mut memory_usage: Option<MemoryInfo> = None;
let mut cpu_percent: Option<f32> = None;
if let Ok(mut process) = Process::new(pid) {
memory_usage = process.memory_info().ok();
cpu_percent = process.cpu_percent().ok();
}
let result = PawResult {
info: PawInfo { memory_usage, cpu_percent, uptime },
process: PawProcess {
cmd: self.command.clone(),
args: self.arguments.clone(),
},
};
callback(result);
sleep(self.duration);
if let Some(status) = child.try_wait()? {
done = PawDone {
stdout: stdout_thread.join().unwrap(),
code: status.code(),
};
break;
}
}
Ok(done)
}
}
+impl PawResult {
+ pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap() }
+}
+
+impl PawDone {
+ pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap() }
+}
+
#[cfg(test)]
mod tests {
use super::*;
use assert_matches::assert_matches;
#[test]
fn watch() {
let paw = Paw::new("node", &["tests/test.js"], 500);
let callback = move |result: PawResult| {
assert_matches!(
result,
PawResult {
info: PawInfo { .. },
process: PawProcess { .. }
}
);
};
match paw.watch(callback) {
Ok(result) => assert_matches!(result, PawDone { .. }),
Err(error) => panic!("{error}"),
}
}
}
diff --git a/src/structs.rs b/src/structs.rs
index 3a67bc7..d838b27 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,27 +1,27 @@
use psutil::process::MemoryInfo;
-use serde_derive::{Deserialize, Serialize};
+use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PawResult {
pub info: PawInfo,
pub process: PawProcess,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PawProcess {
pub cmd: String,
pub args: Vec<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PawInfo {
pub uptime: u128,
pub memory_usage: Option<MemoryInfo>,
pub cpu_percent: Option<f32>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PawDone {
pub stdout: String,
pub code: Option<i32>,
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Dec 16, 3:24 AM (5 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
484906
Default Alt Text
(5 KB)
Attached To
Mode
R7 Paw
Attached
Detach File
Event Timeline
Log In to Comment