move job scheduling to DB

This commit is contained in:
Bryan Van Deusen
2026-01-24 23:50:09 -05:00
parent 61e9336eef
commit dc6755a0c2
8 changed files with 50 additions and 12 deletions
+1 -2
View File
@@ -29,10 +29,9 @@ PORT=8080
# Download settings
# DOWNLOAD_PARALLEL_LIMIT: Max concurrent downloads
# DOWNLOAD_RATE_LIMIT: Seconds between requests (to avoid rate limiting)
# DEFAULT_CHECK_INTERVAL: Seconds between automatic checks for new content
# Check interval is configured per-source in the web UI (Settings page)
DOWNLOAD_PARALLEL_LIMIT=3
DOWNLOAD_RATE_LIMIT=3.0
DEFAULT_CHECK_INTERVAL=3600
# Logging level (DEBUG, INFO, WARNING, ERROR)
LOG_LEVEL=INFO
+23
View File
@@ -31,6 +31,29 @@ async def get_or_create_extension_api_key(session: AsyncSession) -> str:
return new_key
async def get_setting_value(session: AsyncSession, key: str, default=None):
"""Get a setting value from the database, falling back to defaults.
Args:
session: Database session
key: Setting key (e.g., 'download.schedule_interval')
default: Fallback if not in database or DEFAULT_SETTINGS
Returns:
The setting value
"""
result = await session.execute(
select(Setting).where(Setting.key == key)
)
setting = result.scalar()
if setting:
return setting.value
# Fall back to DEFAULT_SETTINGS, then to provided default
return DEFAULT_SETTINGS.get(key, default)
@bp.route("", methods=["GET"])
async def get_all_settings():
"""Get all application settings."""
+7 -1
View File
@@ -8,6 +8,7 @@ from sqlalchemy.orm import selectinload
from app.models.source import Source
from app.models.subscription import Subscription
from app.tasks.downloads import download_source
from app.api.settings import get_setting_value
bp = Blueprint("sources", __name__)
@@ -100,12 +101,17 @@ async def create_source():
if existing.scalar():
return jsonify({"error": "Source with this platform and URL already exists"}), 409
# Get default check interval from database settings
default_interval = await get_setting_value(
session, "download.schedule_interval", 3600
)
source = Source(
subscription_id=data["subscription_id"],
platform=data["platform"],
url=data["url"],
enabled=data.get("enabled", True),
check_interval=data.get("check_interval", 3600),
check_interval=data.get("check_interval", default_interval),
metadata_=data.get("metadata", {}),
)
+13 -2
View File
@@ -8,6 +8,7 @@ from sqlalchemy.orm import selectinload
from app.models.subscription import Subscription
from app.models.source import Source
from app.tasks.downloads import download_source
from app.api.settings import get_setting_value
bp = Blueprint("subscriptions", __name__)
@@ -85,6 +86,11 @@ async def create_subscription():
metadata_=data.get("metadata", {}),
)
# Get default check interval from database settings
default_interval = await get_setting_value(
session, "download.schedule_interval", 3600
)
# Add sources if provided
sources_data = data.get("sources", [])
for source_data in sources_data:
@@ -94,7 +100,7 @@ async def create_subscription():
platform=source_data["platform"],
url=source_data["url"],
enabled=source_data.get("enabled", True),
check_interval=source_data.get("check_interval", 3600),
check_interval=source_data.get("check_interval", default_interval),
metadata_=source_data.get("metadata", {}),
)
subscription.sources.append(source)
@@ -254,12 +260,17 @@ async def add_source_to_subscription(subscription_id: int):
# Store name before commit (attributes expire after commit)
subscription_name = subscription.name
# Get default check interval from database settings
default_interval = await get_setting_value(
session, "download.schedule_interval", 3600
)
source = Source(
subscription_id=subscription_id,
platform=data["platform"],
url=data["url"],
enabled=data.get("enabled", True),
check_interval=data.get("check_interval", 3600),
check_interval=data.get("check_interval", default_interval),
metadata_=data.get("metadata", {}),
)
+1 -1
View File
@@ -25,7 +25,7 @@ class Settings(BaseSettings):
# Download settings
download_parallel_limit: int = 3
download_rate_limit: float = 3.0
default_check_interval: int = 3600 # seconds
# Note: check_interval is now per-source and stored in database
# Server
host: str = "0.0.0.0"
+5 -2
View File
@@ -28,10 +28,13 @@ celery_app.conf.update(
)
# Celery Beat schedule for periodic tasks
# Note: The scheduler runs frequently (every 60s) but only triggers downloads
# for sources whose individual check_interval has elapsed. Per-source intervals
# are stored in the database and can be configured via the UI.
celery_app.conf.beat_schedule = {
"check-sources-hourly": {
"check-sources-scheduler": {
"task": "app.tasks.downloads.scheduled_check",
"schedule": settings.default_check_interval, # Default: every hour
"schedule": 60, # Run every 60 seconds to check for due sources
},
"cleanup-old-downloads-daily": {
"task": "app.tasks.downloads.cleanup_old_downloads",
-2
View File
@@ -22,7 +22,6 @@ services:
- SECRET_KEY=${SECRET_KEY:-dev-secret-key-not-for-production}
- DOWNLOAD_PARALLEL_LIMIT=${DOWNLOAD_PARALLEL_LIMIT:-3}
- DOWNLOAD_RATE_LIMIT=${DOWNLOAD_RATE_LIMIT:-3.0}
- DEFAULT_CHECK_INTERVAL=${DEFAULT_CHECK_INTERVAL:-3600}
- LOG_LEVEL=DEBUG
- DEBUG=true
volumes:
@@ -47,7 +46,6 @@ services:
- SECRET_KEY=${SECRET_KEY:-dev-secret-key-not-for-production}
- DOWNLOAD_PARALLEL_LIMIT=${DOWNLOAD_PARALLEL_LIMIT:-3}
- DOWNLOAD_RATE_LIMIT=${DOWNLOAD_RATE_LIMIT:-3.0}
- DEFAULT_CHECK_INTERVAL=${DEFAULT_CHECK_INTERVAL:-3600}
- LOG_LEVEL=DEBUG
- DEBUG=true
volumes:
-2
View File
@@ -20,7 +20,6 @@ services:
- SECRET_KEY=${SECRET_KEY}
- DOWNLOAD_PARALLEL_LIMIT=${DOWNLOAD_PARALLEL_LIMIT:-3}
- DOWNLOAD_RATE_LIMIT=${DOWNLOAD_RATE_LIMIT:-3.0}
- DEFAULT_CHECK_INTERVAL=${DEFAULT_CHECK_INTERVAL:-3600}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
volumes:
- ${DATA_DOWNLOADS:-downloads}:/data/downloads
@@ -43,7 +42,6 @@ services:
- SECRET_KEY=${SECRET_KEY}
- DOWNLOAD_PARALLEL_LIMIT=${DOWNLOAD_PARALLEL_LIMIT:-3}
- DOWNLOAD_RATE_LIMIT=${DOWNLOAD_RATE_LIMIT:-3.0}
- DEFAULT_CHECK_INTERVAL=${DEFAULT_CHECK_INTERVAL:-3600}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
volumes:
- ${DATA_DOWNLOADS:-downloads}:/data/downloads