From 60bfa277d0730c541c5a16859a0793196877f389 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sat, 31 Aug 2019 07:07:07 +1200 Subject: [PATCH 1/2] Experiment with async/await-enabled ps --- Cargo.lock | 32 ++++++++----------- Cargo.toml | 3 +- src/commands/ps.rs | 71 ++++++++++++++++++++++++++++--------------- src/object.rs | 1 - src/object/process.rs | 29 ------------------ 5 files changed, 60 insertions(+), 76 deletions(-) delete mode 100644 src/object/process.rs diff --git a/Cargo.lock b/Cargo.lock index 02440e0c3..bf713a132 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -641,11 +641,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "doc-comment" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "dtoa" version = "0.4.4" @@ -821,6 +816,15 @@ dependencies = [ "futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "futures-timer" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "futures-util-preview" version = "0.3.0-alpha.18" @@ -1566,6 +1570,7 @@ dependencies = [ "enum-utils 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-async-stream 0.1.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures_codec 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "getset 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1582,6 +1587,7 @@ dependencies = [ "nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1602,7 +1608,6 @@ dependencies = [ "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "surf 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sysinfo 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2619,18 +2624,6 @@ dependencies = [ "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "sysinfo" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tempfile" version = "3.1.0" @@ -3181,7 +3174,6 @@ dependencies = [ "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" -"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum dunce 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0ad6bf6a88548d1126045c413548df1453d9be094a8ab9fd59bf1fdd338da4f" "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" @@ -3204,6 +3196,7 @@ dependencies = [ "checksum futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ee7de0c1c9ed23f9457b0437fec7663ce64d9cc3c906597e714e529377b5ddd1" "checksum futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "efa8f90c4fb2328e381f8adfd4255b4a2b696f77d1c63a3dee6700b564c4e4b5" "checksum futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e9b65a2481863d1b78e094a07e9c0eed458cc7dc6e72b22b7138b8a67d924859" +"checksum futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f9eb554aa23143abc64ec4d0016f038caf53bb7cbc3d91490835c54edc96550" "checksum futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "7df53daff1e98cc024bf2720f3ceb0414d96fbb0a94f3cad3a5c3bf3be1d261c" "checksum futures_codec 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "36552cd31353fd135114510d53b8d120758120c36aa636a9341970f9efb1e4a0" "checksum getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "34f33de6f0ae7c9cb5e574502a562e2b512799e32abb801cd1e79ad952b62b49" @@ -3393,7 +3386,6 @@ dependencies = [ "checksum syn 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c65d951ab12d976b61a41cf9ed4531fc19735c6e6d84a4bb1453711e762ec731" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e80b8831c5a543192ffc3727f01cf0e57579c6ac15558e3048bfb5708892167b" -"checksum sysinfo 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a8e841d2045e01c28343a09841a4c2323d0e936dbb813c95d6c76d13a88668d2" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" diff --git a/Cargo.toml b/Cargo.toml index 08a1272db..ba12a4557 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ documentation = "https://book.nushell.sh" [dependencies] rustyline = "5.0.2" -sysinfo = "0.9.2" chrono = { version = "0.4.7", features = ["serde"] } derive-new = "0.5.7" prettytable-rs = "0.8.0" @@ -77,6 +76,8 @@ textwrap = {version = "0.11.0", features = ["term_size"]} rawkey = {version = "0.1.2", optional = true } clipboard = {version = "0.5", optional = true } shellexpand = "1.0.0" +futures-timer = "0.3.0" +pin-utils = "0.1.0-alpha.4" [features] raw-key = ["rawkey", "neso"] diff --git a/src/commands/ps.rs b/src/commands/ps.rs index 0dd9a1a6c..d2a86487c 100644 --- a/src/commands/ps.rs +++ b/src/commands/ps.rs @@ -1,8 +1,13 @@ use crate::commands::WholeStreamCommand; use crate::errors::ShellError; -use crate::object::process::process_dict; +use crate::object::TaggedDictBuilder; use crate::prelude::*; -use sysinfo::SystemExt; +use std::time::Duration; +use std::usize; + +use futures::stream::{StreamExt, TryStreamExt}; +use heim::process::{self as process, Process, ProcessResult}; +use heim::units::{ratio, Ratio}; pub struct PS; @@ -24,28 +29,44 @@ impl WholeStreamCommand for PS { } } -fn ps(args: CommandArgs, _registry: &CommandRegistry) -> Result { - let system; +async fn usage(process: Process) -> ProcessResult<(process::Process, Ratio)> { + let usage_1 = process.cpu_usage().await?; + futures_timer::Delay::new(Duration::from_millis(100)).await?; + let usage_2 = process.cpu_usage().await?; - #[cfg(target_os = "linux")] - { - system = sysinfo::System::new(); - } - - #[cfg(not(target_os = "linux"))] - { - use sysinfo::RefreshKind; - let mut sy = sysinfo::System::new_with_specifics(RefreshKind::new().with_processes()); - sy.refresh_processes(); - - system = sy; - } - let list = system.get_process_list(); - - let list = list - .into_iter() - .map(|(_, process)| process_dict(process, Tag::unknown_origin(args.call_info.name_span))) - .collect::>(); - - Ok(list.from_input_stream()) + Ok((process, usage_2 - usage_1)) +} + +fn ps(args: CommandArgs, registry: &CommandRegistry) -> Result { + let args = args.evaluate_once(registry)?; + let span = args.name_span(); + + let stream = async_stream_block! { + let processes = process::processes() + .map_ok(|process| { + // Note that there is no `.await` here, + // as we want to pass the returned future + // into the `.try_buffer_unordered`. + usage(process) + }) + .try_buffer_unordered(usize::MAX); + pin_utils::pin_mut!(processes); + + while let Some(res) = processes.next().await { + let (process, usage) = res.unwrap(); + + let mut dict = TaggedDictBuilder::new(Tag::unknown_origin(span)); + dict.insert("pid", Value::int(process.pid())); + if let Ok(name) = process.name().await { + dict.insert("name", Value::string(name)); + } + if let Ok(status) = process.status().await { + dict.insert("status", Value::string(format!("{:?}", status))); + } + dict.insert("cpu", Value::float(usage.get::() as f64)); + yield ReturnSuccess::value(dict.into_tagged_value()); + } + }; + + Ok(stream.to_output_stream()) } diff --git a/src/object.rs b/src/object.rs index 743a09cf6..dc5ecfc08 100644 --- a/src/object.rs +++ b/src/object.rs @@ -4,7 +4,6 @@ pub(crate) mod dict; pub(crate) mod files; pub(crate) mod into; pub(crate) mod meta; -pub(crate) mod process; pub(crate) mod types; #[allow(unused)] diff --git a/src/object/process.rs b/src/object/process.rs deleted file mode 100644 index a5b8e9ccd..000000000 --- a/src/object/process.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::object::{TaggedDictBuilder, Value}; -use crate::prelude::*; -use itertools::join; -use sysinfo::ProcessExt; - -pub(crate) fn process_dict(proc: &sysinfo::Process, tag: impl Into) -> Tagged { - let mut dict = TaggedDictBuilder::new(tag); - - let cmd = proc.cmd(); - - let cmd_value = if cmd.len() == 0 { - Value::nothing() - } else { - Value::string(join(cmd, "")) - }; - - dict.insert("pid", Value::int(proc.pid() as i64)); - dict.insert("status", Value::string(proc.status().to_string())); - dict.insert("cpu", Value::float(proc.cpu_usage() as f64)); - //dict.insert("name", Value::string(proc.name())); - match cmd_value { - Value::Primitive(Primitive::Nothing) => { - dict.insert("name", Value::string(proc.name())); - } - _ => dict.insert("name", cmd_value), - } - - dict.into_tagged_value() -} From c3abb3b6871f87d96c85d0015fb9f978e16aa920 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sat, 31 Aug 2019 07:28:10 +1200 Subject: [PATCH 2/2] Fix unwrap --- src/commands/ps.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/commands/ps.rs b/src/commands/ps.rs index d2a86487c..370b7b73d 100644 --- a/src/commands/ps.rs +++ b/src/commands/ps.rs @@ -53,18 +53,18 @@ fn ps(args: CommandArgs, registry: &CommandRegistry) -> Result() as f64)); + yield ReturnSuccess::value(dict.into_tagged_value()); } - if let Ok(status) = process.status().await { - dict.insert("status", Value::string(format!("{:?}", status))); - } - dict.insert("cpu", Value::float(usage.get::() as f64)); - yield ReturnSuccess::value(dict.into_tagged_value()); } };