Spaces:
Sleeping
Sleeping
| """ | |
| Cache Tier - SQLite caching layer | |
| First tier in the chain - returns cached articles if available. | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| from typing import Any | |
| from src.tiers.base import BaseTier, TierContext, TierResult | |
| logger = logging.getLogger(__name__) | |
| class CacheTier(BaseTier): | |
| """ | |
| Cache tier for returning previously scraped articles. | |
| Priority: 0 (first in chain) | |
| """ | |
| name = "cache" | |
| priority = 0 | |
| def __init__(self) -> None: | |
| super().__init__() | |
| self._initialized = False | |
| async def initialize(self) -> None: | |
| """Initialize cache connection.""" | |
| self._initialized = True | |
| self.logger.debug("Cache tier initialized") | |
| async def cleanup(self) -> None: | |
| """Cleanup cache resources.""" | |
| self._initialized = False | |
| def can_handle(self, ctx: TierContext) -> bool: | |
| """Cache handles all URLs unless force refresh.""" | |
| return not ctx.force_refresh | |
| async def try_scrape(self, ctx: TierContext) -> TierResult: | |
| """ | |
| Try to get article from cache. | |
| Args: | |
| ctx: Context with URL | |
| Returns: | |
| Cached article or failure | |
| """ | |
| try: | |
| from src.database import get_article | |
| article = get_article(ctx.url) | |
| if article: | |
| self.logger.info(f"Cache hit: {ctx.url}") | |
| return TierResult( | |
| success=True, | |
| data=article, | |
| tier_name=self.name, | |
| cached=True, | |
| ) | |
| self.logger.debug(f"Cache miss: {ctx.url}") | |
| return TierResult( | |
| success=False, | |
| error="Not in cache", | |
| tier_name=self.name, | |
| ) | |
| except Exception as e: | |
| self.logger.error(f"Cache error: {e}") | |
| return TierResult( | |
| success=False, | |
| error=str(e), | |
| tier_name=self.name, | |
| ) | |