Hone logo
Hone
Problems

Minimal Async Runtime in Rust

This challenge asks you to implement a simplified asynchronous runtime in Rust. Building a basic runtime is a fundamental exercise in understanding asynchronous programming and provides a deeper appreciation for how frameworks like Tokio and async-std operate. Your runtime will manage a single task, allowing it to execute asynchronously and yield control when necessary.

Problem Description

You are to create a minimal asynchronous runtime that can execute a single asynchronous task. The runtime should:

  1. Accept an asynchronous function (a Future) as input. This function represents the task to be executed.
  2. Execute the future to completion. The runtime should block until the future resolves (either successfully or with an error).
  3. Provide a simple run function that takes the future and executes it within the runtime.
  4. Use async/await syntax. The runtime should leverage Rust's built-in asynchronous features.
  5. Handle potential panics within the future. If the future panics, the runtime should catch the panic and return an Err result.

The runtime does not need to support multiple tasks concurrently. It's a single-task executor. The focus is on understanding the core mechanics of driving a future to completion.

Examples

Example 1:

Input: A future that immediately resolves with the value 42.
Output: Ok(42)
Explanation: The runtime should execute the future, which completes immediately, and return the resolved value.

Example 2:

Input: A future that sleeps for 100 milliseconds and then resolves with the value "Hello".
Output: Ok("Hello")
Explanation: The runtime should yield control to allow the sleep to occur, then execute the future to completion and return the resolved value.

Example 3:

Input: A future that panics with the message "Something went wrong!".
Output: Err(String::from("Something went wrong!"))
Explanation: The runtime should catch the panic within the future and return an `Err` result containing the panic message.

Constraints

  • The runtime must be implemented using Rust's async/await syntax.
  • The runtime should not rely on external crates (e.g., Tokio, async-std) beyond the standard library.
  • The run function should return a Result<T, String>, where T is the type of the future's resolved value. If the future panics, the Err variant should contain the panic message.
  • The runtime should handle panics gracefully, preventing the program from crashing.
  • The runtime should be thread-safe. While it only handles one task at a time, it should be designed in a way that avoids data races if extended later.

Notes

  • Consider using a Pin<&mut dyn Future<Output = T> + Unpin> to hold the future. The Unpin bound is important because you'll be moving the future around.
  • The Future::poll method is the core of asynchronous execution. You'll need to repeatedly poll the future until it returns Poll::Ready.
  • Think about how to handle the Pending state returned by Future::poll. This is where the runtime yields control.
  • You can use std::thread::sleep for simulating asynchronous operations that take time.
  • Error handling is crucial. Ensure your runtime gracefully handles panics and other potential errors.
  • This is a simplified runtime. Real-world runtimes are significantly more complex, handling multiple tasks, timers, I/O, and more. The goal here is to understand the fundamental principles.
Loading editor...
rust