Files
thrilltrack-explorer/django/PHASE_7_CELERY_COMPLETE.md
pacnpal d6ff4cc3a3 Add email templates for user notifications and account management
- Created a base email template (base.html) for consistent styling across all emails.
- Added moderation approval email template (moderation_approved.html) to notify users of approved submissions.
- Added moderation rejection email template (moderation_rejected.html) to inform users of required changes for their submissions.
- Created password reset email template (password_reset.html) for users requesting to reset their passwords.
- Developed a welcome email template (welcome.html) to greet new users and provide account details and tips for using ThrillWiki.
2025-11-08 15:34:04 -05:00

452 lines
14 KiB
Markdown

# Phase 7: Background Tasks with Celery - COMPLETE ✅
**Completion Date:** November 8, 2025
**Status:** Successfully Implemented
## Overview
Phase 7 implements a comprehensive background task processing system using Celery with Redis as the message broker. This phase adds asynchronous processing capabilities for long-running operations, scheduled tasks, and email notifications.
## What Was Implemented
### 1. Celery Infrastructure ✅
- **Celery App Configuration** (`config/celery.py`)
- Auto-discovery of tasks from all apps
- Signal handlers for task failure/success logging
- Integration with Sentry for error tracking
- **Django Integration** (`config/__init__.py`)
- Celery app loaded on Django startup
- Shared task decorators available throughout the project
### 2. Email System ✅
- **Email Templates** (`templates/emails/`)
- `base.html` - Base template with ThrillWiki branding
- `welcome.html` - Welcome email for new users
- `password_reset.html` - Password reset instructions
- `moderation_approved.html` - Submission approved notification
- `moderation_rejected.html` - Submission rejection notification
- **Email Configuration**
- Development: Console backend (emails print to console)
- Production: SMTP/SendGrid (configurable via environment variables)
### 3. Background Tasks ✅
#### Media Tasks (`apps/media/tasks.py`)
- `process_uploaded_image(photo_id)` - Post-upload image processing
- `cleanup_rejected_photos(days_old=30)` - Remove old rejected photos
- `generate_photo_thumbnails(photo_id)` - On-demand thumbnail generation
- `cleanup_orphaned_cloudflare_images()` - Remove orphaned images
- `update_photo_statistics()` - Update photo-related statistics
#### Moderation Tasks (`apps/moderation/tasks.py`)
- `send_moderation_notification(submission_id, status)` - Email notifications
- `cleanup_expired_locks()` - Remove stale moderation locks
- `send_batch_moderation_summary(moderator_id)` - Daily moderator summaries
- `update_moderation_statistics()` - Update moderation statistics
- `auto_unlock_stale_reviews(hours=1)` - Auto-unlock stale submissions
- `notify_moderators_of_queue_size()` - Alert on queue threshold
#### User Tasks (`apps/users/tasks.py`)
- `send_welcome_email(user_id)` - Welcome new users
- `send_password_reset_email(user_id, token, reset_url)` - Password resets
- `cleanup_expired_tokens()` - Remove expired JWT tokens
- `send_account_notification(user_id, type, data)` - Generic notifications
- `cleanup_inactive_users(days_inactive=365)` - Flag inactive accounts
- `update_user_statistics()` - Update user statistics
- `send_bulk_notification(user_ids, subject, message)` - Bulk emails
- `send_email_verification_reminder(user_id)` - Verification reminders
#### Entity Tasks (`apps/entities/tasks.py`)
- `update_entity_statistics(entity_type, entity_id)` - Update entity stats
- `update_all_statistics()` - Bulk statistics update
- `generate_entity_report(entity_type, entity_id)` - Generate reports
- `cleanup_duplicate_entities()` - Detect duplicates
- `calculate_global_statistics()` - Global statistics
- `validate_entity_data(entity_type, entity_id)` - Data validation
### 4. Scheduled Tasks (Celery Beat) ✅
Configured in `config/settings/base.py`:
| Task | Schedule | Purpose |
|------|----------|---------|
| `cleanup-expired-locks` | Every 5 minutes | Remove expired moderation locks |
| `cleanup-expired-tokens` | Daily at 2 AM | Clean up expired JWT tokens |
| `update-all-statistics` | Every 6 hours | Update entity statistics |
| `cleanup-rejected-photos` | Weekly Mon 3 AM | Remove old rejected photos |
| `auto-unlock-stale-reviews` | Every 30 minutes | Auto-unlock stale reviews |
| `check-moderation-queue` | Every hour | Check queue size threshold |
| `update-photo-statistics` | Daily at 1 AM | Update photo statistics |
| `update-moderation-statistics` | Daily at 1:30 AM | Update moderation statistics |
| `update-user-statistics` | Daily at 4 AM | Update user statistics |
| `calculate-global-statistics` | Every 12 hours | Calculate global statistics |
### 5. Service Integration ✅
- **PhotoService** - Triggers `process_uploaded_image` on photo creation
- **ModerationService** - Sends email notifications on approval/rejection
- Error handling ensures service operations don't fail if tasks fail to queue
### 6. Monitoring ✅
- **Flower** - Web-based Celery monitoring (production only)
- **Task Logging** - Success/failure logging for all tasks
- **Sentry Integration** - Error tracking for failed tasks
## Setup Instructions
### Development Setup
1. **Install Redis** (if not using eager mode):
```bash
# macOS with Homebrew
brew install redis
brew services start redis
# Or using Docker
docker run -d -p 6379:6379 redis:latest
```
2. **Configure Environment** (`.env`):
```env
# Redis Configuration
REDIS_URL=redis://localhost:6379/0
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/1
# Email Configuration (Development)
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
DEFAULT_FROM_EMAIL=noreply@thrillwiki.com
SITE_URL=http://localhost:8000
```
3. **Run Celery Worker** (in separate terminal):
```bash
cd django
celery -A config worker --loglevel=info
```
4. **Run Celery Beat** (in separate terminal):
```bash
cd django
celery -A config beat --loglevel=info
```
5. **Development Mode** (No Redis Required):
- Tasks run synchronously when `CELERY_TASK_ALWAYS_EAGER = True` (default in `local.py`)
- Useful for debugging and testing without Redis
### Production Setup
1. **Configure Environment**:
```env
# Redis Configuration
REDIS_URL=redis://your-redis-host:6379/0
CELERY_BROKER_URL=redis://your-redis-host:6379/0
CELERY_RESULT_BACKEND=redis://your-redis-host:6379/1
# Email Configuration (Production)
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.sendgrid.net
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=apikey
EMAIL_HOST_PASSWORD=your-sendgrid-api-key
DEFAULT_FROM_EMAIL=noreply@thrillwiki.com
SITE_URL=https://thrillwiki.com
# Flower Monitoring (Optional)
FLOWER_ENABLED=True
FLOWER_BASIC_AUTH=username:password
```
2. **Run Celery Worker** (systemd service):
```ini
[Unit]
Description=ThrillWiki Celery Worker
After=network.target redis.target
[Service]
Type=forking
User=www-data
Group=www-data
WorkingDirectory=/var/www/thrillwiki/django
Environment="PATH=/var/www/thrillwiki/venv/bin"
ExecStart=/var/www/thrillwiki/venv/bin/celery -A config worker \
--loglevel=info \
--logfile=/var/log/celery/worker.log \
--pidfile=/var/run/celery/worker.pid
[Install]
WantedBy=multi-user.target
```
3. **Run Celery Beat** (systemd service):
```ini
[Unit]
Description=ThrillWiki Celery Beat
After=network.target redis.target
[Service]
Type=forking
User=www-data
Group=www-data
WorkingDirectory=/var/www/thrillwiki/django
Environment="PATH=/var/www/thrillwiki/venv/bin"
ExecStart=/var/www/thrillwiki/venv/bin/celery -A config beat \
--loglevel=info \
--logfile=/var/log/celery/beat.log \
--pidfile=/var/run/celery/beat.pid \
--schedule=/var/run/celery/celerybeat-schedule
[Install]
WantedBy=multi-user.target
```
4. **Run Flower** (optional):
```bash
celery -A config flower --port=5555 --basic_auth=$FLOWER_BASIC_AUTH
```
Access at: `https://your-domain.com/flower/`
## Testing
### Manual Testing
1. **Test Photo Upload Task**:
```python
from apps.media.tasks import process_uploaded_image
result = process_uploaded_image.delay(photo_id)
print(result.get()) # Wait for result
```
2. **Test Email Notification**:
```python
from apps.moderation.tasks import send_moderation_notification
result = send_moderation_notification.delay(str(submission_id), 'approved')
# Check console output for email
```
3. **Test Scheduled Task**:
```python
from apps.moderation.tasks import cleanup_expired_locks
result = cleanup_expired_locks.delay()
print(result.get())
```
### Integration Testing
Test that services properly queue tasks:
```python
# Test PhotoService integration
from apps.media.services import PhotoService
service = PhotoService()
photo = service.create_photo(file, user)
# Task should be queued automatically
# Test ModerationService integration
from apps.moderation.services import ModerationService
ModerationService.approve_submission(submission_id, reviewer)
# Email notification should be queued
```
## Task Catalog
### Task Retry Configuration
All tasks implement retry logic:
- **Max Retries:** 2-3 (task-dependent)
- **Retry Delay:** 60 seconds base (exponential backoff)
- **Failure Handling:** Logged to Sentry and application logs
### Task Priority
Tasks are executed in the order they're queued. For priority queuing, configure Celery with multiple queues:
```python
# config/celery.py (future enhancement)
CELERY_TASK_ROUTES = {
'apps.media.tasks.process_uploaded_image': {'queue': 'media'},
'apps.moderation.tasks.send_moderation_notification': {'queue': 'notifications'},
}
```
## Monitoring & Debugging
### View Task Status
```python
from celery.result import AsyncResult
result = AsyncResult('task-id-here')
print(result.state) # PENDING, STARTED, SUCCESS, FAILURE
print(result.info) # Result or error details
```
### Flower Dashboard
Access Flower at `/flower/` (production only) to:
- View active tasks
- Monitor worker status
- View task history
- Inspect failed tasks
- Retry failed tasks
### Logs
```bash
# View worker logs
tail -f /var/log/celery/worker.log
# View beat logs
tail -f /var/log/celery/beat.log
# View Django logs (includes task execution)
tail -f django/logs/django.log
```
## Troubleshooting
### Common Issues
1. **Tasks not executing**
- Check Redis connection: `redis-cli ping`
- Verify Celery worker is running: `ps aux | grep celery`
- Check for errors in worker logs
2. **Emails not sending**
- Verify EMAIL_BACKEND configuration
- Check SMTP credentials
- Review email logs in console (development)
3. **Scheduled tasks not running**
- Ensure Celery Beat is running
- Check Beat logs for scheduling errors
- Verify CELERY_BEAT_SCHEDULE configuration
4. **Task failures**
- Check Sentry for error reports
- Review worker logs
- Test task in Django shell
### Performance Tuning
```python
# Increase worker concurrency
celery -A config worker --concurrency=4
# Use different pool implementation
celery -A config worker --pool=gevent
# Set task time limits
CELERY_TASK_TIME_LIMIT = 30 * 60 # 30 minutes (already configured)
```
## Configuration Options
### Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `REDIS_URL` | Yes* | `redis://localhost:6379/0` | Redis connection URL |
| `CELERY_BROKER_URL` | Yes* | Same as REDIS_URL | Celery message broker |
| `CELERY_RESULT_BACKEND` | Yes* | `redis://localhost:6379/1` | Task result storage |
| `EMAIL_BACKEND` | No | Console (dev) / SMTP (prod) | Email backend |
| `EMAIL_HOST` | Yes** | - | SMTP host |
| `EMAIL_PORT` | Yes** | 587 | SMTP port |
| `EMAIL_HOST_USER` | Yes** | - | SMTP username |
| `EMAIL_HOST_PASSWORD` | Yes** | - | SMTP password |
| `DEFAULT_FROM_EMAIL` | Yes | `noreply@thrillwiki.com` | From email address |
| `SITE_URL` | Yes | `http://localhost:8000` | Site URL for emails |
| `FLOWER_ENABLED` | No | False | Enable Flower monitoring |
| `FLOWER_BASIC_AUTH` | No** | - | Flower authentication |
\* Not required if using eager mode in development
\*\* Required for production email sending
## Next Steps
### Future Enhancements
1. **Task Prioritization**
- Implement multiple queues for different priority levels
- Critical tasks (password reset) in high-priority queue
- Bulk operations in low-priority queue
2. **Advanced Monitoring**
- Set up Prometheus metrics
- Configure Grafana dashboards
- Add task duration tracking
3. **Email Improvements**
- Add plain text email versions
- Implement email templates for all notification types
- Add email preference management
4. **Scalability**
- Configure multiple Celery workers
- Implement auto-scaling based on queue size
- Add Redis Sentinel for high availability
5. **Additional Tasks**
- Backup generation tasks
- Data export tasks
- Analytics report generation
## Success Criteria ✅
All success criteria for Phase 7 have been met:
- ✅ Celery workers running successfully
- ✅ Tasks executing asynchronously
- ✅ Email notifications working (console backend configured)
- ✅ Scheduled tasks configured and ready
- ✅ Flower monitoring configured for production
- ✅ Error handling and retries implemented
- ✅ Integration with existing services complete
- ✅ Comprehensive documentation created
## Files Created
- `config/celery.py` - Celery app configuration
- `config/__init__.py` - Updated to load Celery
- `templates/emails/base.html` - Base email template
- `templates/emails/welcome.html` - Welcome email
- `templates/emails/password_reset.html` - Password reset email
- `templates/emails/moderation_approved.html` - Approval notification
- `templates/emails/moderation_rejected.html` - Rejection notification
- `apps/media/tasks.py` - Media processing tasks
- `apps/moderation/tasks.py` - Moderation workflow tasks
- `apps/users/tasks.py` - User management tasks
- `apps/entities/tasks.py` - Entity statistics tasks
- `PHASE_7_CELERY_COMPLETE.md` - This documentation
## Files Modified
- `config/settings/base.py` - Added Celery Beat schedule, SITE_URL, DEFAULT_FROM_EMAIL
- `config/urls.py` - Added Flower URL routing
- `apps/media/services.py` - Integrated photo processing task
- `apps/moderation/services.py` - Integrated email notification tasks
## Dependencies
All dependencies were already included in `requirements/base.txt`:
- `celery[redis]==5.3.4`
- `django-celery-beat==2.5.0`
- `django-celery-results==2.5.1`
- `flower==2.0.1`
## Summary
Phase 7 successfully implements a complete background task processing system with Celery. The system handles:
- Asynchronous image processing
- Email notifications for moderation workflow
- Scheduled maintenance tasks
- Statistics updates
- Token cleanup
The implementation is production-ready with proper error handling, retry logic, monitoring, and documentation.
**Phase 7: COMPLETE**