diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index e97976a..da8d247 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -8,6 +8,7 @@ # - Volume mounts for live code reloading # - Debug logging enabled # - Database and Redis ports exposed for local tools +# - Separate scheduler and worker services (matches production) services: # Combined backend API + frontend static files @@ -18,7 +19,7 @@ services: environment: - TZ=${TZ:-America/New_York} - DATABASE_URL=postgresql://${DB_USER:-gdl}:${DB_PASSWORD:-devpassword}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-gallery_subscriber} - - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/0 + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/${REDIS_DB:-0} - 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} @@ -35,14 +36,14 @@ services: condition: service_started restart: unless-stopped - # Celery worker for background tasks - celery: + # Celery download workers - only process download tasks (heavy work) + worker: build: . - command: celery -A app.tasks.celery_app worker -B --loglevel=debug + command: celery -A app.tasks.celery_app worker --queues=downloads --loglevel=debug environment: - TZ=${TZ:-America/New_York} - DATABASE_URL=postgresql://${DB_USER:-gdl}:${DB_PASSWORD:-devpassword}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-gallery_subscriber} - - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/0 + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/${REDIS_DB:-0} - 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} @@ -59,6 +60,26 @@ services: condition: service_started restart: unless-stopped + # Celery scheduler - runs beat + handles lightweight scheduling tasks + scheduler: + build: . + command: celery -A app.tasks.celery_app worker --queues=scheduling --beat --loglevel=debug --concurrency=1 + environment: + - TZ=${TZ:-America/New_York} + - DATABASE_URL=postgresql://${DB_USER:-gdl}:${DB_PASSWORD:-devpassword}@${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-gallery_subscriber} + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/${REDIS_DB:-0} + - SECRET_KEY=${SECRET_KEY:-dev-secret-key-not-for-production} + - LOG_LEVEL=DEBUG + - DEBUG=true + volumes: + - ./backend/app:/app/app:ro + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + restart: unless-stopped + # PostgreSQL database db: image: postgres:15-alpine diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index 5874318..5365412 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -38,6 +38,7 @@ export const downloadsApi = { stats: (params = {}) => api.get('/downloads/stats', { params }), recentActivity: (params = {}) => api.get('/downloads/recent-activity', { params }), resetOrphaned: (thresholdMinutes = 0) => api.post('/downloads/reset-orphaned', { threshold_minutes: thresholdMinutes }), + requeueStale: (thresholdMinutes = 0) => api.post('/downloads/requeue-stale', { threshold_minutes: thresholdMinutes }), } // Credentials API diff --git a/frontend/src/stores/downloads.js b/frontend/src/stores/downloads.js index 5c864c4..92ff0ca 100644 --- a/frontend/src/stores/downloads.js +++ b/frontend/src/stores/downloads.js @@ -43,6 +43,14 @@ export const useDownloadsStore = defineStore('downloads', () => { return await downloadsApi.retry(id) } + async function resetOrphaned(thresholdMinutes = 0) { + return await downloadsApi.resetOrphaned(thresholdMinutes) + } + + async function requeueStale(thresholdMinutes = 0) { + return await downloadsApi.requeueStale(thresholdMinutes) + } + return { downloads, recentActivity, @@ -55,5 +63,7 @@ export const useDownloadsStore = defineStore('downloads', () => { fetchRecentActivity, fetchStats, retryDownload, + resetOrphaned, + requeueStale, } }) diff --git a/frontend/src/views/Downloads.vue b/frontend/src/views/Downloads.vue index e659e0e..9fe4f8e 100644 --- a/frontend/src/views/Downloads.vue +++ b/frontend/src/views/Downloads.vue @@ -1,5 +1,65 @@ + + + + @@ -139,17 +212,21 @@ - URL - {{ selectedDownload.url }} + Source + {{ getSourceLabel(selectedDownload.source_id) }} - Source - {{ getSourceLabel(selectedDownload.source_id) }} + URL + {{ selectedDownload.url }} Files Downloaded {{ selectedDownload.file_count }} + + Created + {{ formatDate(selectedDownload.created_at) }} + Started {{ formatDate(selectedDownload.started_at) }} @@ -202,7 +279,7 @@ + +