Hone logo
Hone
Problems

Asynchronous Data Streams with Async Iterators

Asynchronous iterators are a powerful feature in Python that allow you to process data streams in a non-blocking manner, particularly useful when dealing with I/O-bound operations like network requests or file reads. This challenge will guide you in implementing an asynchronous iterator that fetches data from a simulated asynchronous source. Successfully completing this challenge will demonstrate your understanding of async def, async for, and the __aiter__ and __anext__ methods.

Problem Description

You are tasked with creating an asynchronous iterator called AsyncDataSource that simulates fetching data from an asynchronous source. The source provides data in chunks after a short delay. The iterator should:

  1. Simulate an Asynchronous Source: The AsyncDataSource should take a total_items parameter representing the total number of items to be fetched and a chunk_size parameter representing the number of items fetched in each chunk. It should also take a delay parameter representing the time (in seconds) to wait before yielding a chunk.
  2. Implement __aiter__: This method should return the iterator object itself (i.e., self).
  3. Implement __anext__: This method should:
    • Wait for the specified delay using asyncio.sleep().
    • Check if there are more items to fetch. If not, raise StopAsyncIteration.
    • Fetch a chunk of chunk_size items.
    • Return the chunk as a list.
    • Decrement the number of remaining items.

Examples

Example 1:

Input: total_items=10, chunk_size=3, delay=0.5
Output:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10]
Explanation: The iterator fetches 10 items in chunks of 3, with a 0.5-second delay between each chunk. The last chunk contains only 1 item.

Example 2:

Input: total_items=5, chunk_size=2, delay=1.0
Output:
[1, 2]
[3, 4]
[5]
Explanation: The iterator fetches 5 items in chunks of 2, with a 1-second delay. The last chunk contains only 1 item.

Example 3: (Edge Case - total_items < chunk_size)

Input: total_items=2, chunk_size=3, delay=0.2
Output:
[1, 2]
Explanation: The iterator fetches 2 items in a chunk of size 3.  Since there are fewer items than the chunk size, the entire remaining data is returned in the first chunk.

Constraints

  • total_items will be a positive integer.
  • chunk_size will be a positive integer.
  • delay will be a non-negative float.
  • The asyncio.sleep() function should be used to simulate the asynchronous delay.
  • The iterator should handle the case where total_items is less than chunk_size correctly.
  • The items fetched should be sequential integers starting from 1.

Notes

  • You'll need to import the asyncio module.
  • Consider using a class to encapsulate the iterator's state (e.g., remaining items).
  • Remember that __anext__ is an asynchronous method, so it must be defined using async def.
  • The StopAsyncIteration exception signals the end of the iteration.
  • Focus on correctly implementing the asynchronous behavior and handling edge cases. Performance is not a primary concern for this challenge.
Loading editor...
python