chore: init commit

in worker.../repo/GITFOLDER.zip is the .git folder.
This commit is contained in:
2026-08-11 14:44:09 -04:00
parent 0012380fd3
commit 2854619bc9
782 changed files with 65944 additions and 0 deletions

View File

@@ -0,0 +1,275 @@
# Job Scheduling with Solid Queue
This document explains how stock-related jobs are scheduled to run automatically using Rails 8's **Solid Queue** system.
## Overview
The application uses **Solid Queue** for both job processing and recurring job scheduling. This provides a unified, database-backed system that works identically across all environments (development, staging, production).
### Scheduled Jobs
1. **OrderExecutionJob** - Executes pending stock orders (both buy and sell) at 1:00 AM ET weekdays only (Monday-Friday)
2. **StockPricesUpdateJob** - Updates stock prices from Alpha Vantage API (automatically triggered after OrderExecutionJob)
3. **MonthlyPortfolioSnapshotJob** - Creates portfolio snapshots on the last day of each month at 11:00 PM ET
## Configuration
### Recurring Jobs Configuration
The scheduling configuration is defined in [`config/recurring.yml`](../config/recurring.yml):
```yaml
development: &default
daily_order_execution:
class: OrderExecutionJob
queue: default
schedule: "0 6 * * 1-5" # Monday-Friday at 6 AM UTC (1 AM EST)
monthly_portfolio_snapshot:
class: MonthlyPortfolioSnapshotJob
queue: default
schedule: "0 23 L * *" # Last day of month at 11 PM UTC
production:
<<: *default
```
### Worker Configuration
Worker settings are configured in [`config/queue.yml`](../config/queue.yml):
```yaml
default: &default
dispatchers:
- polling_interval: 1
batch_size: 500
workers:
- queues: "*"
threads: 3
processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %>
polling_interval: 0.1
```
## Job Execution Flow
### Daily Stock Processing (1:00 AM ET, Weekdays Only)
1. **OrderExecutionJob** runs first (scheduled via recurring.yml)
- Processes all pending buy/sell orders
- Applies transaction fees
- **Automatically triggers** StockPricesUpdateJob upon completion
- **Only runs Monday through Friday** (weekdays)
2. **StockPricesUpdateJob** runs second (triggered by OrderExecutionJob)
- Updates current stock prices from Alpha Vantage API
- Saves yesterday's prices for historical tracking
- **Only runs on weekdays** (when OrderExecutionJob runs)
### Monthly Portfolio Snapshots (Last Day, 11:00 PM ET)
3. **MonthlyPortfolioSnapshotJob** runs monthly
- Creates portfolio snapshots for all students
- Used for performance tracking and reporting
## Deployment Instructions
### Development Environment
Start the Solid Queue worker to process jobs:
```bash
# Start worker in development
bin/jobs
# Or run in background
bin/jobs &
```
Test job scheduling:
```bash
# Test manual job execution
rails console
OrderExecutionJob.perform_later
SolidQueue::Job.count # Should show queued jobs
```
### Staging Deployment
#### Heroku
```bash
# Deploy code changes
git push heroku main
# Scale up job worker (uses Procfile configuration)
heroku ps:scale job=1 -a your-app-name
# Verify worker is running
heroku ps -a your-app-name
```
#### AWS/Traditional Servers
Create a systemd service for the worker:
```ini
# /etc/systemd/system/stocks-solid-queue.service
[Unit]
Description=Stocks in the Future - Solid Queue Worker
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/path/to/your/app
ExecStart=/path/to/your/app/bin/jobs
Restart=always
RestartSec=5
Environment=RAILS_ENV=production
Environment=JOB_CONCURRENCY=3
[Install]
WantedBy=multi-user.target
```
```bash
# Enable and start service
sudo systemctl enable stocks-solid-queue
sudo systemctl start stocks-solid-queue
sudo systemctl status stocks-solid-queue
```
## Job Dependencies
### Prerequisites
1. **Database Access**: All job data is stored in PostgreSQL
2. **Active Worker Process**: Must have `bin/jobs` running
3. **API Access**: StockPricesUpdateJob requires Alpha Vantage API access
4. **Environment Variables**: `ALPHA_VANTAGE_API_KEY` must be set
### Database Tables
Solid Queue uses these database tables:
- `solid_queue_jobs` - Main job queue
- `solid_queue_ready_executions` - Jobs ready to run
- `solid_queue_recurring_executions` - Recurring job schedules
- `solid_queue_failed_executions` - Failed jobs for debugging
## Monitoring
### Job Status Monitoring
```bash
# Check job counts
rails console
SolidQueue::Job.count # Total jobs
SolidQueue::Job.where(finished_at: nil).count # Pending jobs
SolidQueue::FailedExecution.count # Failed jobs
# View recent jobs
SolidQueue::Job.last(10).each do |job|
puts "#{job.class_name} - #{job.finished_at ? 'Complete' : 'Pending'}"
end
```
### Heroku Monitoring
```bash
# View job logs
heroku logs --tail -a your-app-name | grep -E "(OrderExecutionJob|StockPricesUpdateJob)"
# Check worker status
heroku ps -a your-app-name
# Check job queue
heroku run rails runner "puts SolidQueue::Job.count" -a your-app-name
```
### Log Files
Monitor execution through:
- Rails logs: `log/production.log` (contains job execution details)
- Worker logs: Output from `bin/jobs` process
- Heroku logs: `heroku logs --tail -a your-app-name`
## Manual Execution
For testing or emergency runs:
```bash
# Rails console
rails console
OrderExecutionJob.perform_later # Queue job
OrderExecutionJob.perform_now # Run immediately
StockPricesUpdateJob.perform_later # Queue job
MonthlyPortfolioSnapshotJob.perform_later # Queue monthly job
# Command line
rails runner "OrderExecutionJob.perform_later"
```
## Troubleshooting
### Common Issues
1. **Jobs not running**:
- Check worker process is running (`bin/jobs`)
- Verify database connection
- Check `solid_queue_jobs` table exists
2. **Jobs failing**:
- Check `SolidQueue::FailedExecution.all` for error details
- Verify API keys are set (`ALPHA_VANTAGE_API_KEY`)
- Check database connectivity
3. **Recurring jobs not scheduling**:
- Verify `config/recurring.yml` syntax
- Check worker is running with recurring job support
- Confirm time zone settings
4. **Performance issues**:
- Adjust `JOB_CONCURRENCY` environment variable
- Monitor database table sizes
- Check API rate limits
### Debugging Commands
```bash
# View failed jobs with errors
rails console
SolidQueue::FailedExecution.all.each do |failed_job|
puts "#{failed_job.job.class_name}: #{failed_job.error}"
end
# Check recurring job schedules
SolidQueue::RecurringTask.all.each do |task|
puts "#{task.class_name}: #{task.schedule}"
end
# Clear all jobs (emergency only)
SolidQueue::Job.delete_all
```
## Time Zone Considerations
- **Recurring jobs use server time zone**
- **Jobs are scheduled in Eastern Time (America/New_York)**
- **Heroku**: Runs in UTC, so 1 AM ET = 6 AM UTC (EST) or 5 AM UTC (EDT)
- **AWS**: Configure server time zone or adjust schedule accordingly
- **Weekday scheduling**: OrderExecutionJob and StockPricesUpdateJob only run Monday-Friday
## Migration from Previous System
This system replaces the previous setup that used:
- ❌ **whenever gem** (removed) - No longer needed
- ❌ **Heroku Scheduler** (removed) - No longer needed
- ❌ **Delayed Job** (removed) - Replaced by Solid Queue
- ❌ **cron jobs** (removed) - No longer needed
### Benefits of New System
- ✅ **Environment independent** - Works same on Heroku and AWS
- ✅ **Database-backed** - More reliable than cron
- ✅ **Built-in monitoring** - Better visibility into job status
- ✅ **Job chaining** - Automatic OrderExecution → StockPrices flow
- ✅ **Rails 8 native** - Optimized performance and integration
## Related Documentation
- [Solid Queue Migration Guide](solid-queue-migration.md) - Technical migration details
- [Heroku Deployment Guide](heroku-deployment-solid-queue.md) - Deployment instructions
- [Orders and Transactions](orders-and-transactions.md) - Business logic overview