Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Nicolas Bigaouette
    @nbigaouette

    Hi all! I want to use heim::process::Process::cpu_usage(). In the docs it says:

    It is suggested to wait for a while with help of any async timer (for accuracy recommended delay should be at least 100 ms), call this method once again and subtract former CpuUsage from the new one.

    How much waiting is "too long"? I have a non-async program with a 5 second periodicity custom loop. Can I do the diff between two periods of my loop?

    Because my program is not async, I use futures::executor::block_on() a single async fn that awaits all heim calls. And since I am blocking, I would prefer not to have to sleep between the two calls to cpu_usage().
    svartalf
    @svartalf
    @nbigaouette nushell is using 100ms as a delay value, for example
    @nbigaouette you can use any async delay, so it would not block everything
    Nicolas Bigaouette
    @nbigaouette
    Thanks @svartalf ! The thing is that my program is not async. Everything is blocking. It's a simple state machine which loops around a couple of states. In one of those states I want to use heim. So I have a single async fn that is wrapped in a tokio::Runtime::block_on(). Since there is not much to await in that async function, adding an async delay will end up simply sleeping completely during the length of the delay. To prevent to add this kind of "artificial" delay to the remaining of the program, I though I could use the main program state machine loop to do the cpu measurements. This loop has a periodicity of ~5 seconds. So every time the program comes back to the specific state, it could call cpu_usage() and subtract the calculated value with the one stored from the previous state iteration. So instead of a 100ms difference I would have a 5 seconds difference. My question is: could that be problematic for the cpu_usage() calculation to have a 5 seconds delay?
    Nicolas Bigaouette
    @nbigaouette
    From what I understand the cpu_usage() call gives an instantaneous value (some kind of cpu counter?) that needs to be compared with a reference value.
    So I guess I should be safe to do the comparison after the 5 seconds...
    Nicolas Bigaouette
    @nbigaouette
    @svartalf Also, I was wondering why there is a heim::process::cpu_usage() but not a heim::cpu::cpu_usage()? I have to manually do the same calculation manually to get a percentage of global CPU usage. Or is there something that is fundamentally different?
    svartalf
    @svartalf
    @nbigaouette yeah, you got it right, single call to cpu_usage creates an instantenious value and two of them can be compared into real CPU usage. I think it is okay to have a 5 seconds delay, but you will receive an average value for this period, so if there were any spikes, you will miss them
    @nbigaouette as for per-CPU usage, it is not implemented yet: heim-rs/heim#177
    Nicolas Bigaouette
    @nbigaouette
    Thanks for the clarification @svartalf ! Using a 5 seconds delay does work. As you mentioned I do see an average though, but that's ok for my use case.
    Nicolas Bigaouette
    @nbigaouette

    I have another question for you. The CpuUsage diff I get is too low. I don't get the percentage of CPU usage I expect. If I launch htop the cpu usage % reported is relative to a single core. So if I have one thread that spin-loop (or any CPU bound task) htop reports "100%". If a process spin-loop 2 threads, I get 200% cpu usage by htop. Now using heim I get half this number... I think it's related to # cores vs # cpus. I have a macbook pro with a quad-core hyper threading:

    sysctl hw.logicalcpu; sysctl hw.physicalcpu
    hw.logicalcpu: 8
    hw.physicalcpu: 4

    If I measure using heim::process::cpu_usage() the following:

    async fn run() {
        let process = heim::process::current().await.unwrap();
    
        let cpu_usage_before = process.cpu_usage().await.unwrap();
        let child1 = std::thread::spawn(move || {
            // spin loop
            for _i in 0..100_000_000 {}
        });
        let child2 = std::thread::spawn(move || {
            // spin loop
            for _i in 0..100_000_000 {}
        });
        child1.join().unwrap();
        child2.join().unwrap();
        let cpu_usage_after = process.cpu_usage().await.unwrap();
        println!(
            "Usage (%): {}",
            (cpu_usage_after - cpu_usage_before).get::<heim::units::ratio::percent>()
        );
    }
    
    fn main() {
        let mut rt = tokio::runtime::Runtime::new().unwrap();
        rt.block_on(run());
    }

    I get 100%, not 200% as I expected...

    Am I missing something? Could it be a bug in heim?

    Nicolas Bigaouette
    @nbigaouette
    Should I scale the result by logicalcpu/physicalcpu? Should the doc mention this behaviour?

    cpu_usage()'s doc only mention:

    calculated CPU usage might exceed 100 % if the process is running multiple threads on different CPU cores.

    Hum... looks like a bug. impl Sub<CpuUsage> for CpuUsage multiplies and devide the time by cpu_count, resulting in a no-op.
    svartalf
    @svartalf
    @nbigaouette hmm, it is interesting, thank you for noting. I assume it happens on macOS?
    svartalf
    @svartalf
    As for the code you are linked, it was a total ripoff from the Python psutil: https://github.com/giampaolo/psutil/blob/e65cc95de72828caed74c7916530dd74fca351e3/psutil/__init__.py#L958-L1048
    Obviously, there might be a bug, but so far I can't say nothing specific and it should be investigated
    Nicolas Bigaouette
    @nbigaouette

    Thanks, yes, I'm on macos.

    I've opened heim-rs/heim#199 to track this. I think psutils's implementation is also wrongly using cpu_count! :D

    svartalf
    @svartalf
    Feels weird, psutil is heavy used like by everyone :)
    Anyway, thank you for an issue, I'll try to take a look into it
    svartalf
    @svartalf
    @nbigaouette hey, quick follow-up: I fixed that heap corruption issue for good with a prettier code version, I want to test it a bit more, but so far it works fine in my Windows VM.
    Not sure if I'll find any reasonable sanitizers / valgrind analogs for Windows, but if there will be no other issues tomorrow, I'll merge and publish it
    Nicolas Bigaouette
    @nbigaouette
    Thanks @svartalf ! I'll try 0.0.10 in the next few days and make sure it's gone. Thanks a lot!!
    Nicolas Bigaouette
    @nbigaouette
    A quick try suggest the issue is gone with 0.0.10. Seemed to have changed the behaviour though. physical_count() now returns 2 in my VM which exposes 2 CPUs. With 0.0.9, physical_count() reported 1. Windows' task manager reports 1 socket and 2 virtual cpu. Shouldn't physical_count() return 1 in this case..?
    So on macos directly I get 4 and 8 for physical and virtual, which is expected.
    svartalf
    @svartalf
    Ummmm....
    Let me check this thing. Basically I ported the psutil functionality (once again :) ), but I might've added some logic bug in process
    Nicolas Bigaouette
    @nbigaouette
    Regarding the CPU% calculation, I've opened a bug on psutil since it seems to suffer from the same problem: giampaolo/psutil#1700
    svartalf
    @svartalf
    @nbigaouette cool, I would love to know what Giampaolo thinks about this case
    svartalf
    @svartalf
    @cjbassi hey! I just got pointed out by sysinfo crate author that that comparison page in the heim repo is terribly outdated and I was wondering, should I update details about psutil or not.
    It seems like it is going under the major rewrite right now, so I'm not sure if it will be a good time to aggregate all the data
    Caleb Bassi
    @cjbassi
    Sure! The rewrite is mostly done. It was mostly restructuring the folder structure and A
    Woops, and api as inspired by heim actually, so thanks for that :)
    I also have this file which details the current functions implemented per platform https://github.com/rust-psutil/rust-psutil/blob/master/platform_support.md
    svartalf
    @svartalf
    @cjbassi meh, I was copying the Python' psutil scheme mostly, so let's call it an artistic inspiration for both of us :)
    Thank you for the link, that will be very helpful
    Govardhan G D
    @govardhangdg
    Hello! I was trying to write an example program similar to https://github.com/giampaolo/psutil/blob/master/scripts/netstat.py in rust using the heim crate. But I wasn't able to find any utility in the crate that gives information about the currently open ports. There are functions that give information about the interfaces present in the computer in the heim::net subcrate, but I could find nothing regrading the ports. Can anyone help me with this?
    svartalf
    @svartalf
    @govardhangdg hey! Yeah, this example is blocked right now, because the things you need are not implemented yet :(
    It is pointed in here: heim-rs/heim#205
    Govardhan G D
    @govardhangdg
    Thanks!
    svartalf
    @svartalf
    it is a bump, I know :) Anything in this issue, which is not marked as "blocked by" can be implemented right now with 0.1.x version
    Govardhan G D
    @govardhangdg
    @svartalf I am trying to port the iotop example from the psutil project. I've set up the required TUI part using the cursive crate. But I am facing problem because the cursive crate, imo, doesn't support async code. There I need to provide a closure(or function) which will be called at regular intervals in order to update the screen contents. But for our purposes, this closure would have to be an async one. but I don't think it's possible to mix async code and non-async code in this manner. And also I am not able to find any other TUI crate that supports async code.
    So, I have come up with an idea. This may not be idiomatic. As the TUI part only consumes the values (i.e, doesn't produce or modify them) and only our async code (using the heim crate) produces the values, which will be later consumed by TUI. So, this imo is just another consumer-producer problem. But I don't know how to join the two parts. Maybe some kind of producer-consumer queue or in the worst case, keep some global variables which will be modified and read from by the producer and consumer regions respectively (but it's definitely not idiomatic)
    Any suggestions?
    svartalf
    @svartalf
    @govardhangdg I see no problem in blocking till future resolves
    As long it will has a comment like "You should be aware that mixing sync and async code together might be bad", it is more than okay for examples
    Govardhan G D
    @govardhangdg
    In https://github.com/heim-rs/heim/blob/master/examples/top.rs , is there any particular reason why tokio::pin! macro is being used in line 28?
    svartalf
    @svartalf
    @govardhangdg yes, processes stream needs to be pinned before polled, see https://docs.rs/tokio/0.2.13/tokio/macro.pin.html
    Govardhan G D
    @govardhangdg
    Although I understand why the concept of pinning is needed in rust, sometimes it's just too confusing for me to identify the cases where it is required and cases where it's not :\
    svartalf
    @svartalf
    Same :)
    Usually it just says that method poll is not found or Unpin is not implemented for some deeply hidden closure..
    Andrew M.
    @ephemeron_gitlab
    A question: in the disk module, is there any particular reason why the Partition struct offers no method to show space usage, which can instead be obtained only by passing a path to usage(path)?
    It feels unexpected, at first glance.
    svartalf
    @svartalf
    @ephemeron_gitlab the only reason is I had not thought about it :D
    It is a nice addition, though, I'll file the issue