mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-07 07:08:31 +00:00
Add thread-safe, async-compatible event bus with read–write locking and handler dependency ordering. Remove blinker dependency and implement direct dispatch. Improve type safety, error handling, and deterministic event synchronization. Refactor tests to auto-wait for async handlers, ensure clean teardown, and add comprehensive concurrency coverage. Replace thread-local state in AgentEvaluator with instance-based locking for correct cross-thread access. Enhance tracing reliability and event finalization.
40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
"""Test utilities for CrewAI tests."""
|
|
|
|
import asyncio
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
|
|
|
|
def wait_for_event_handlers(timeout: float = 5.0) -> None:
|
|
"""Wait for all pending event handlers to complete.
|
|
|
|
This helper ensures all sync and async handlers finish processing before
|
|
proceeding. Useful in tests to make assertions deterministic.
|
|
|
|
Args:
|
|
timeout: Maximum time to wait in seconds.
|
|
"""
|
|
from crewai.events.event_bus import crewai_event_bus
|
|
|
|
loop = getattr(crewai_event_bus, "_loop", None)
|
|
|
|
if loop and not loop.is_closed():
|
|
|
|
async def _wait_for_async_tasks() -> None:
|
|
tasks = {
|
|
t for t in asyncio.all_tasks(loop) if t is not asyncio.current_task()
|
|
}
|
|
if tasks:
|
|
await asyncio.gather(*tasks, return_exceptions=True)
|
|
|
|
future = asyncio.run_coroutine_threadsafe(_wait_for_async_tasks(), loop)
|
|
try:
|
|
future.result(timeout=timeout)
|
|
except Exception: # noqa: S110
|
|
pass
|
|
|
|
crewai_event_bus._sync_executor.shutdown(wait=True)
|
|
crewai_event_bus._sync_executor = ThreadPoolExecutor(
|
|
max_workers=10,
|
|
thread_name_prefix="CrewAISyncHandler",
|
|
)
|