Hone logo
Hone
Problems

Asynchronous Data Fetching with Rust Futures

This challenge will guide you through the implementation of asynchronous functions in Rust to fetch data concurrently. You will learn how to define and use async fn, await, and Futures, which are fundamental concepts for building efficient and responsive applications that handle I/O-bound operations without blocking the main thread.

Problem Description

Your task is to create a Rust program that simulates fetching data from multiple remote sources concurrently. You will implement an asynchronous function that represents a single data fetch operation. This function should simulate network latency using tokio::time::sleep and return some simulated data. Then, you will write a main asynchronous function that calls this data fetching function multiple times, waits for all of them to complete, and aggregates their results.

Key Requirements:

  1. fetch_data(id: u32) function:
    • This function must be declared as async fn.
    • It should accept a u32 id as input.
    • Inside the function, it should simulate a network delay of a random duration between 100ms and 500ms.
    • It should return a String representing the fetched data, for example, format!("Data for ID: {}", id).
  2. main function:
    • This function must also be declared as async fn.
    • It should call fetch_data for a predefined number of IDs (e.g., 5 IDs: 1, 2, 3, 4, 5).
    • It should initiate these fetches concurrently, meaning they should run in parallel rather than sequentially.
    • It should wait for all initiated fetches to complete.
    • Finally, it should print the aggregated results in the order of their IDs.
  3. Use tokio runtime: The solution must utilize the tokio runtime to execute the asynchronous code.

Expected Behavior:

The program should demonstrate that the data fetches are happening concurrently. The total execution time should be significantly less than the sum of individual fetch times, indicating parallel execution. The output should be a list of strings, each representing the data fetched for a specific ID, printed in ascending order of the IDs.

Edge Cases:

  • Consider what happens if one of the async fn calls were to return an error (though for this challenge, we will assume successful completion).
  • The random delay ensures that the fetches will complete in an unpredictable order, testing your ability to aggregate results correctly.

Examples

Example 1:

Input: None (The program runs and initiates 5 fetches internally)
Output:
Data for ID: 1
Data for ID: 2
Data for ID: 3
Data for ID: 4
Data for ID: 5
Explanation: The program initiates asynchronous calls to fetch data for IDs 1 through 5. These calls run concurrently. Once all calls have completed, the results are collected and printed in the order of the IDs (1 to 5), regardless of the order in which they finished executing. The total execution time will be closer to the longest individual fetch time rather than the sum of all fetch times.

Constraints

  • The number of concurrent fetches will be between 3 and 10.
  • The simulated delay for each fetch will be a random duration between 100ms and 500ms.
  • The program must compile and run successfully using the tokio runtime.
  • Imports should be minimal and relevant to asynchronous programming with tokio.

Notes

  • You'll need to add tokio as a dependency in your Cargo.toml file.
  • Consider using tokio::spawn to launch futures concurrently and futures::future::join_all to await their completion.
  • The rand crate can be used for generating random delays.
  • Remember to mark your main function with #[tokio::main] to set up the runtime.
Loading editor...
rust