0

I have a function that try to call some services, one of them ( external service) have a lot of issues, and never give any answers and I would like to kill it after certain time.

I would like to find any crate that could set a timeout calling a function. But I can't manage to find one ?

fn main() {
    let result = retry::retry(Fixed::from_millis(3000).take(5), || {
            let possibly_return = function_maybe_never_return();
        match possibly_return {
            Ok(kubeconfig) => OperationResult::Ok(kubeconfig),
            Err(err) => Err(err)
        }
    });
    match result {
            Ok(downloaded) => info!("OK !!")
            Err(e) => Error!("Unable to ... after many retries {:?}", e),
    };
}

fn function_maybe_never_return(){
    
}

I want to use retry crate on it to retrying operation.

maathor
  • 121
  • 1
  • 3
  • 12
  • You cannot kill a function. – n. m. could be an AI Dec 04 '20 at 14:39
  • yes, I know, but do you have any workarround ? – maathor Dec 04 '20 at 14:41
  • You can run the process on a seperate thread [and terminate it after a timeout](https://stackoverflow.com/questions/36181719/what-is-the-correct-way-in-rust-to-create-a-timeout-for-a-thread-or-a-function) – Ibraheem Ahmed Dec 04 '20 at 15:04
  • 1
    You can use `std::process::Command` to spawn an external process (possibly the program you're running with a special command-line flag that tells it to run the function) and terminate it after a timeout. That is the only portable way of achieving your goal. – user4815162342 Dec 04 '20 at 15:18
  • You can kill a process so perhaps run one. – n. m. could be an AI Dec 04 '20 at 18:11
  • Hi @maathor. If you can change the function then it should be possible to make it async and use one of existing libraries to make your call to external service async as well. The it'll be much easier to cancel function execution. Please let me know if you are interested in that kind of solution then I can provide you more details. – MaxV Dec 05 '20 at 19:43

1 Answers1

0

If you have an async runtime like tokio, you can. I had a similar requirement. I had a blocking function which I need to cancel after a set timeout. Here's how I did it.

fn long_running_function() -> Result<()> {
    std::thread::sleep(std::time::Duration::from_secs(1000));
    Ok(())
}

async fn call_long_running_function() {
    tokio::time::timeout(std::time::Duration::from_secs(2), tokio::task::spawn_blocking(move ||long_running_function())).await.unwrap()

}

Here, the long running blocking function will be called inside a tokio::spawn_blocking which is further wrapped in a tokio::time::timeout(), so when that deadline exceeds, the long_running_function will die with a Deadline error.

I'm sure there are other better ways too. This is how I had it working for my use case, as I was already working on async code base.

nohup
  • 3,105
  • 3
  • 27
  • 52