""" Utility module for cache management in the SciPaperLoader application. This module contains functions for managing the hourly quota cache and other caching mechanisms. """ from datetime import datetime from .models import ActivityLog # Global cache for hourly quota HOURLY_QUOTA_CACHE = { 'hour': None, # Current hour 'quota': None, # Calculated quota 'last_config_update': None, # Last time volume or schedule config was updated } def invalidate_hourly_quota_cache(calculate_function=None): """ Invalidate the hourly quota cache when configuration changes. Args: calculate_function (callable, optional): Function to recalculate quota immediately. If None, recalculation will happen during next get_cached_hourly_quota() call. """ global HOURLY_QUOTA_CACHE HOURLY_QUOTA_CACHE['last_config_update'] = None # If a calculation function is provided, recalculate immediately if calculate_function: current_hour = datetime.now().hour quota = calculate_function() HOURLY_QUOTA_CACHE['hour'] = current_hour HOURLY_QUOTA_CACHE['quota'] = quota HOURLY_QUOTA_CACHE['last_config_update'] = datetime.now() ActivityLog.log_scraper_activity( action="cache_recalculated", status="info", description=f"Hourly quota immediately recalculated after config change: {quota} papers" ) else: # Log the cache invalidation ActivityLog.log_scraper_activity( action="cache_invalidated", status="info", description="Hourly quota cache was invalidated due to configuration changes" ) def get_cached_hourly_quota(calculate_function): """ Get the cached hourly quota if it's still valid, or recalculate if needed. Args: calculate_function: Function to call when recalculation is needed Returns: int: Number of papers to download this hour """ global HOURLY_QUOTA_CACHE current_hour = datetime.now().hour # Check if we need to recalculate if (HOURLY_QUOTA_CACHE['hour'] != current_hour or HOURLY_QUOTA_CACHE['quota'] is None or HOURLY_QUOTA_CACHE['last_config_update'] is None): # Recalculate and update cache quota = calculate_function() HOURLY_QUOTA_CACHE['hour'] = current_hour HOURLY_QUOTA_CACHE['quota'] = quota HOURLY_QUOTA_CACHE['last_config_update'] = datetime.now() # Log cache update ActivityLog.log_scraper_activity( action="cache_updated", status="info", description=f"Hourly quota cache updated for hour {current_hour}: {quota} papers" ) return quota else: # Use cached value return HOURLY_QUOTA_CACHE['quota']