import asyncio
import time
async def fetch_data_from_source(source_id: int):
"""Simulates fetching data from a source with a delay."""
await asyncio.sleep(0.1 * (source_id + 1))
return f"data_from_{source_id}"
async def process_and_yield(generator_id: int):
"""A sub-generator that fetches and yields results."""
for i in range(2):
yield await fetch_data_from_source(f"{generator_id}-{i}")
async def delegate_processing(level: int):
"""A generator that delegates to another generator using 'yield from'."""
# The issue is suspected to arise from this delegation pattern.
yield from process_and_yield(f"delegator_{level}")
async def main():
start_time = time.monotonic()
results = []
try:
async for result in delegate_processing(1):
results.append(result)
await asyncio.sleep(0.05) # Small sleep to simulate other work
except asyncio.CancelledError:
print("Main: Task cancelled.")
except Exception as e:
print(f"Main: Caught unexpected exception: {e}")
end_time = time.monotonic()
print(f"Main finished in {end_time - start_time:.2f} seconds. Collected {len(results)} results.")
if __name__ == "__main__":
asyncio.run(main())
Этот код иногда зависает на неопределенный срок, без каких-либо исключений и низкой загрузки ЦП, когда выход из используется в глубоко вложенных асинхронных генераторах. Как можно предотвратить этот тонкий тупик?
async def fetch_data_from_source(source_id: int): """Simulates fetching data from a source with a delay.""" await asyncio.sleep(0.1 * (source_id + 1)) return f"data_from_{source_id}"
async def process_and_yield(generator_id: int): """A sub-generator that fetches and yields results.""" for i in range(2): yield await fetch_data_from_source(f"{generator_id}-{i}")
async def delegate_processing(level: int): """A generator that delegates to another generator using 'yield from'.""" # The issue is suspected to arise from this delegation pattern. yield from process_and_yield(f"delegator_{level}")
async def main(): start_time = time.monotonic() results = [] try: async for result in delegate_processing(1): results.append(result) await asyncio.sleep(0.05) # Small sleep to simulate other work except asyncio.CancelledError: print("Main: Task cancelled.") except Exception as e: print(f"Main: Caught unexpected exception: {e}")
if __name__ == "__main__": asyncio.run(main()) [/code] Этот код иногда зависает на неопределенный срок, без каких-либо исключений и низкой загрузки ЦП, когда выход из используется в глубоко вложенных асинхронных генераторах. Как можно предотвратить этот тонкий тупик?