forked from apify/crawlee-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Fix init of context managers and context handling in `BasicCrawl…
…er` (apify#714) ### Problems - The `EventManager` could be initialized multiple times, such as when running a `Crawler` wrapped inside an `Actor`. - In `crawler.run`, the async context was entered and exited directly, which could lead to issues if the caller had already entered it. This scenario might occur when users provide their own instances of `BrowserPool`, `SessionPool`, `EventManager`, or others. ### Solution - Address these issues by introducing an `active` flag to the existing context managers to prevent multiple initializations. - Implement an `ensure_context` helper and apply it to methods where context management is required. - Fix & improve tests to ensure these cases are covered. ### Others - I added missing names to asyncio tasks.
- Loading branch information
Showing
18 changed files
with
392 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from __future__ import annotations | ||
|
||
import asyncio | ||
from functools import wraps | ||
from typing import Any, Callable, TypeVar | ||
|
||
T = TypeVar('T', bound=Callable[..., Any]) | ||
|
||
|
||
def ensure_context(method: T) -> T: | ||
"""Decorator to ensure the (async) context manager is initialized before calling the method. | ||
Args: | ||
method: The method to wrap. | ||
Returns: | ||
The wrapped method with context checking applied. | ||
""" | ||
|
||
@wraps(method) | ||
def sync_wrapper(self: Any, *args: Any, **kwargs: Any) -> Any: | ||
if not hasattr(self, 'active'): | ||
raise RuntimeError(f'The {self.__class__.__name__} does not have the "active" attribute.') | ||
|
||
if not self.active: | ||
raise RuntimeError(f'The {self.__class__.__name__} is not active. Use it within the context.') | ||
|
||
return method(self, *args, **kwargs) | ||
|
||
@wraps(method) | ||
async def async_wrapper(self: Any, *args: Any, **kwargs: Any) -> Any: | ||
if not hasattr(self, 'active'): | ||
raise RuntimeError(f'The {self.__class__.__name__} does not have the "active" attribute.') | ||
|
||
if not self.active: | ||
raise RuntimeError(f'The {self.__class__.__name__} is not active. Use it within the async context.') | ||
|
||
return await method(self, *args, **kwargs) | ||
|
||
return async_wrapper if asyncio.iscoroutinefunction(method) else sync_wrapper # type: ignore[return-value] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.