""" 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, )