What is remote_handle in futures crate

68 views Asked by At

I was reading through turtle crate and I came across this function remote_handle

I viewed the docs for remote_handle but was unable to understand it.

I was able to understand the first line. But was unable to understand the 2nd line.

Turn this future into a future that yields () on completion and sends its output to another future on a separate task.

This can be used with spawning executors to easily retrieve the result of a future executing on a separate task or thread.

This method is only available when the std feature of this library is activated, and it is activated by default.

My question - Can anyone explain the 2nd line with the help of a small example?

I am trying to understand why it was used in the turtle crate when starting up the backend server.

2

There are 2 answers

0
Chayim Friedman On

Say you have some quite heavy workload that you therefore want to run on a separate task, to allow it to run in a different thread. But this workload also has a result, and you want to retrieve this result from the original task (or a different task). You can spawn a task and execute the future there, and send the result back to the original thread with a oneshot channel. remote_handle() basically abstracts over this. It takes a future which returns something, and gives you back a future that you can execute on the new task (that returns ()), and a handle (also a future) that can be .awaited on the original task, and that will give you the result of the future after it finished executing on the other task (of course, you need to .await it).

0
Kanwar Baweja On

If you have a Rust asynchronous task (a future) that you want to execute concurrently, and you want to be able to monitor or interact with this task from the main thread, you can use a RemoteHandle (remote_handle function) to achieve this.

Sample code:


use futures::prelude::*;
use std::thread;

fn main() {
    let (future, my_handle) = my_async_task().remote_handle();

    // Spawn the asynchronous task on a separate thread using Tokio's runtime. This allows us to execute the asynchronous task concurrently.
    let child_thread = thread::spawn(|| {
        tokio::runtime::Runtime::new().unwrap().block_on(future);
    });

    // We can now interact with the task using the handle from the main thread.
    // For example, we can cancel the task.
     let canceled = my_handle.cancel();

    // Wait for the child thread to complete.
    child_thread.join().unwrap();

    // Print a message depending on whether the task was canceled or completed.
    if canceled {
        println!("Task was canceled!");
    } else {
        println!("Task completed!");
    }
}

// asynchronous task that performs some work and returns a result
// my_async_task is designed to run as a separate task. 
async fn my_async_task() -> i32 {
    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
    42
}