@@ -2047,3 +2047,74 @@ async def error_handler(context: BasicCrawlingContext, error: Exception) -> Requ
20472047 assert error_request is not None
20482048 assert error_request .state == RequestState .DONE
20492049 assert error_request .was_already_handled
2050+
2051+
2052+ @pytest .mark .skipif (sys .version_info [:3 ] < (3 , 11 ), reason = 'asyncio.Barrier was introduced in Python 3.11.' )
2053+ async def test_multiple_crawlers_with_global_event_manager () -> None :
2054+ """Test that multiple crawlers work correctly when using the global event manager."""
2055+
2056+ # Test is skipped in older Python versions.
2057+ from asyncio import Barrier # type:ignore[attr-defined] # noqa: PLC0415
2058+
2059+ rq1 = await RequestQueue .open (alias = 'rq1' )
2060+ rq2 = await RequestQueue .open (alias = 'rq2' )
2061+
2062+ crawler_1 = BasicCrawler (request_manager = rq1 )
2063+ crawler_2 = BasicCrawler (request_manager = rq2 )
2064+
2065+ started_event = asyncio .Event ()
2066+ finished_event = asyncio .Event ()
2067+
2068+ async def launch_crawler_1 () -> None :
2069+ await crawler_1 .run (['https://a.placeholder.com' ])
2070+ finished_event .set ()
2071+
2072+ async def launch_crawler_2 () -> None :
2073+ # Ensure that crawler_1 is already running and has activated event_manager
2074+ await started_event .wait ()
2075+ await crawler_2 .run (['https://b.placeholder.com' ])
2076+
2077+ handler_barrier = Barrier (2 )
2078+
2079+ handler_call = AsyncMock ()
2080+
2081+ @crawler_1 .router .default_handler
2082+ async def handler_1 (context : BasicCrawlingContext ) -> None :
2083+ started_event .set ()
2084+ # Ensure that both handlers are running at the same time.
2085+ await handler_barrier .wait ()
2086+ event_manager = service_locator .get_event_manager ()
2087+
2088+ await handler_call (event_manager .active )
2089+
2090+ @crawler_2 .router .default_handler
2091+ async def handler_2 (context : BasicCrawlingContext ) -> None :
2092+ # Ensure that both handlers are running at the same time.
2093+ await handler_barrier .wait ()
2094+ # Ensure that crawler_1 is finished and closed all active contexts.
2095+ await finished_event .wait ()
2096+ # Check that event manager is active and can be used in the second crawler.
2097+ event_manager = service_locator .get_event_manager ()
2098+
2099+ await handler_call (event_manager .active )
2100+
2101+ await asyncio .gather (
2102+ launch_crawler_1 (),
2103+ launch_crawler_2 (),
2104+ )
2105+
2106+ assert handler_call .call_count == 2
2107+
2108+ first_call = handler_call .call_args_list [0 ]
2109+ second_call = handler_call .call_args_list [1 ]
2110+
2111+ assert first_call [0 ][0 ] is True
2112+ assert second_call [0 ][0 ] is True
2113+
2114+ event_manager = service_locator .get_event_manager ()
2115+
2116+ # After both crawlers are finished, event manager should be inactive.
2117+ assert event_manager .active is False
2118+
2119+ await rq1 .drop ()
2120+ await rq2 .drop ()
0 commit comments