expectrl icon indicating copy to clipboard operation
expectrl copied to clipboard

`interact()` seems consumes too much CPU

Open yinheli opened this issue 2 years ago • 6 comments

Example, following example will cause 100% CPU usage.

fn main() {
    let shell = "bash";
    let mut sh = expectrl::spawn(shell.to_string()).expect("Error while spawning sh");

    println!("Connecting to {}", shell);

    sh.interact().unwrap();
}

yinheli avatar Aug 22 '22 09:08 yinheli

It seems session.try_read is non_blocking, So infinity loop consume too much CPU. Mybe should spawn new thread to do read & write separately.

yinheli avatar Aug 22 '22 10:08 yinheli

Example, following example will cause 100% CPU usage.

Interesting. Good catch.

It seems session.try_read is non_blocking, So infinity loop consume too much CPU. Mybe should spawn new thread to do read & write separately.

Right, because we need to check whether there's something in stdin and in stdout/stderr of a process.

Mybe should spawn new thread to do read & write separately.

It's a good approach. But there might be some different workaround. I have something in mind.

zhiburt avatar Aug 22 '22 18:08 zhiburt

Seems like I've managed it. There's still some todos:

  1. it doesn't yet work on windows.
  2. the feature name is not ideal.
  3. I want to try to add an optional thread spawning as you've suggested.

Do

expectrl = { git = "https://github.com/zhiburt/expectrl/", branch = "reduce_cpu_usage_in_interact", features = ["polling"] }

zhiburt avatar Aug 23 '22 11:08 zhiburt

I want to highlight about your proposal with spawning a thread which will block on read. It works.

But there's no easy way how to stop it. I mean we can't stop it when it's blocked. So the thread will became dangling which brings quite a bit of issues. For example in case of several spawns the threads will compete for the input/output reads.

I guess signals could be used but that's pretty complex. We could terminate it.... but I am not sure about it.

See

a platform invoke call to the Win32 WaitForSingleObject function), neither Thread.Interrupt nor Thread.Abort can take control of the thread until it returns to or calls into managed code

zhiburt avatar Aug 28 '22 13:08 zhiburt

interact feature is too complex. especially you have std & async implements .

yinheli avatar Aug 31 '22 05:08 yinheli

Good morning

interact feature is too complex. especially you have std & async implements.

What do you mean?

zhiburt avatar Aug 31 '22 07:08 zhiburt

Just wanted to let you know that I've just published the feature. You can use 0.6.0 version.

It also brings changes to the interact interface.

zhiburt avatar Sep 24 '22 22:09 zhiburt

Thanks, It's okay now.

yinheli avatar Sep 25 '22 05:09 yinheli