changes to task scheduling and readability change on downloads view
This commit is contained in:
@@ -207,6 +207,41 @@ async def reset_orphaned_downloads():
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
@bp.route("/requeue-stale", methods=["POST"])
|
||||
async def requeue_stale_downloads():
|
||||
"""Re-queue Celery tasks for downloads stuck in 'queued' status.
|
||||
|
||||
Downloads can get stuck in 'queued' database status if the Celery task
|
||||
was lost (e.g., sent to wrong Redis DB, Redis restart, etc.).
|
||||
This endpoint re-sends the Celery tasks for those jobs.
|
||||
"""
|
||||
from app.tasks.maintenance import requeue_stale_jobs, _requeue_all_queued_jobs_async
|
||||
|
||||
data = await request.get_json() or {}
|
||||
threshold_minutes = data.get("threshold_minutes", 0) # 0 = re-queue ALL queued jobs
|
||||
|
||||
try:
|
||||
if threshold_minutes == 0:
|
||||
# Re-queue all queued jobs immediately (synchronous for immediate feedback)
|
||||
result = await _requeue_all_queued_jobs_async()
|
||||
current_app.logger.info(f"Manual re-queue of all queued jobs: {result}")
|
||||
return jsonify({
|
||||
"message": f"Re-queued {result['requeued_count']} queued jobs",
|
||||
"requeued_count": result['requeued_count'],
|
||||
})
|
||||
else:
|
||||
# Queue the task for threshold-based re-queue
|
||||
task = requeue_stale_jobs.delay(threshold_minutes)
|
||||
return jsonify({
|
||||
"message": "Stale job re-queue queued",
|
||||
"task_id": task.id,
|
||||
"threshold_minutes": threshold_minutes,
|
||||
}), 202
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Failed to re-queue stale jobs: {e}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
@bp.route("/stats", methods=["GET"])
|
||||
async def get_stats():
|
||||
"""Get download statistics."""
|
||||
|
||||
@@ -118,8 +118,10 @@ async def update_settings():
|
||||
setting = result.scalar()
|
||||
|
||||
if setting:
|
||||
current_app.logger.info(f"Updating setting '{key}': {setting.value} -> {value} (type: {type(value).__name__})")
|
||||
setting.value = value
|
||||
else:
|
||||
current_app.logger.info(f"Creating setting '{key}': {value} (type: {type(value).__name__})")
|
||||
setting = Setting(key=key, value=value)
|
||||
session.add(setting)
|
||||
|
||||
@@ -321,3 +323,49 @@ async def get_system_info():
|
||||
"download_path": config.download_path,
|
||||
"config_path": config.config_path,
|
||||
})
|
||||
|
||||
|
||||
@bp.route("/debug/schedule-interval", methods=["GET"])
|
||||
async def debug_schedule_interval():
|
||||
"""Debug endpoint to verify schedule_interval setting storage and retrieval.
|
||||
|
||||
Returns detailed information about how the setting is stored and what value
|
||||
the worker would read.
|
||||
"""
|
||||
async with current_app.db_engine.connect() as conn:
|
||||
session = AsyncSession(bind=conn)
|
||||
|
||||
# Query the raw setting from database
|
||||
result = await session.execute(
|
||||
select(Setting).where(Setting.key == "download.schedule_interval")
|
||||
)
|
||||
setting = result.scalar()
|
||||
|
||||
if setting:
|
||||
raw_value = setting.value
|
||||
db_info = {
|
||||
"found_in_database": True,
|
||||
"raw_value": raw_value,
|
||||
"raw_type": type(raw_value).__name__,
|
||||
"as_int": int(raw_value) if raw_value is not None else None,
|
||||
"updated_at": setting.updated_at.isoformat() if setting.updated_at else None,
|
||||
}
|
||||
else:
|
||||
db_info = {
|
||||
"found_in_database": False,
|
||||
"raw_value": None,
|
||||
"raw_type": None,
|
||||
"as_int": None,
|
||||
"updated_at": None,
|
||||
}
|
||||
|
||||
# What the worker would use
|
||||
fallback_value = DEFAULT_SETTINGS.get("download.schedule_interval", 3600)
|
||||
worker_would_use = db_info["as_int"] if db_info["found_in_database"] else fallback_value
|
||||
|
||||
return jsonify({
|
||||
"database": db_info,
|
||||
"default_settings_value": fallback_value,
|
||||
"worker_would_use": worker_would_use,
|
||||
"worker_would_use_hours": worker_would_use / 3600 if worker_would_use else None,
|
||||
})
|
||||
|
||||
@@ -105,7 +105,7 @@ async def create_source():
|
||||
|
||||
# Get default check interval from database settings
|
||||
default_interval = await get_setting_value(
|
||||
session, "download.schedule_interval", 3600
|
||||
session, "download.schedule_interval", 28800
|
||||
)
|
||||
|
||||
source = Source(
|
||||
|
||||
@@ -89,7 +89,7 @@ async def create_subscription():
|
||||
|
||||
# Get default check interval from database settings
|
||||
default_interval = await get_setting_value(
|
||||
session, "download.schedule_interval", 3600
|
||||
session, "download.schedule_interval", 28800
|
||||
)
|
||||
|
||||
# Add sources if provided
|
||||
@@ -263,7 +263,7 @@ async def add_source_to_subscription(subscription_id: int):
|
||||
|
||||
# Get default check interval from database settings
|
||||
default_interval = await get_setting_value(
|
||||
session, "download.schedule_interval", 3600
|
||||
session, "download.schedule_interval", 28800
|
||||
)
|
||||
|
||||
source = Source(
|
||||
|
||||
Reference in New Issue
Block a user