Implementing a Simple Waker System in Rust
This challenge asks you to implement a basic waker system in Rust, mimicking the core functionality of the Waker type used in asynchronous programming. Understanding how wakers work is crucial for grasping the inner workings of Rust's async/await system and building custom asynchronous primitives. You'll be creating a simplified version that allows you to "wake up" a task.
Problem Description
You need to implement a Waker struct and its associated wake method. The Waker should internally hold a closure that, when called, signals that a task should be resumed. The wake method should execute this closure. This is a simplified model; in reality, wakers interact with the runtime to schedule tasks, but here we'll focus on the core signaling mechanism.
Key Requirements:
WakerStruct: Define aWakerstruct that encapsulates a closure.wakeMethod: Implement awakemethod on theWakerstruct. This method should execute the closure stored within theWaker.- Closure Capture: The closure should capture at least one piece of data (e.g., an integer) to demonstrate that closures can be used to store state.
- No Runtime Dependency: The solution should not depend on any external asynchronous runtime libraries (e.g.,
tokio,async-std). This is a standalone implementation.
Expected Behavior:
When wake is called on a Waker instance, the closure it holds should be executed. The closure's execution should have a visible side effect (e.g., printing a message, incrementing a counter).
Edge Cases to Consider:
- What happens if
wakeis called multiple times? (The closure should execute each time.) - How can you ensure the closure is not executed prematurely? (This is a simplified system, so we're not focusing on complex synchronization, but consider the implications.)
Examples
Example 1:
Input:
```rust
let captured_value = 42;
let waker = Waker::new(move || {
println!("Waker triggered! Captured value: {}", captured_value);
});
waker.wake();
waker.wake();
Output:
Waker triggered! Captured value: 42
Waker triggered! Captured value: 42
Explanation: The Waker is created with a closure that prints a message including the captured value. Calling wake() twice executes the closure twice, resulting in the message being printed twice.
Example 2:
Input:
```rust
let mut counter = 0;
let waker = Waker::new(move || {
counter += 1;
println!("Waker triggered! Counter: {}", counter);
});
waker.wake();
waker.wake();
Output:
Waker triggered! Counter: 1
Waker triggered! Counter: 2
Explanation: The closure increments a counter and prints its value. Calling wake() twice increments the counter and prints the updated value each time.
Constraints
- The solution must be written in Rust.
- The
Wakerstruct andwakemethod must be implemented as described. - The closure captured by the
Wakermust capture at least one piece of data. - The solution should not use any external asynchronous runtime libraries.
- The code should be well-formatted and easy to understand.
Notes
- This is a simplified waker system. Real-world wakers interact with the asynchronous runtime to schedule tasks.
- Focus on the core concept of signaling a task to be resumed.
- Consider how the closure's capture list affects its behavior.
- Think about the implications of calling
wakemultiple times. While not a primary focus, understanding this behavior is important. - The
Wakerstruct itself doesn't need to be thread-safe in this simplified scenario.