Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ gem 'commonmarker'
gem 'country_select'
gem 'csl-styles'
gem 'csv'
gem 'daemons'
gem 'delayed_job_active_record'
gem 'redis', '~> 5.0'
gem 'sidekiq', '~> 7.0'
gem 'docsplit', git: 'https://github.com/documentcloud/docsplit.git'
gem 'doorkeeper'
gem 'dotenv-rails'
Expand Down
118 changes: 118 additions & 0 deletions MIGRATION_NOTES_SIDEKIQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Migration from delayed_job to Sidekiq

This document outlines the migration from delayed_job to Sidekiq for background job processing in SEEK.

## What Changed

SEEK has migrated from using delayed_job with ActiveRecord backend to Sidekiq with Redis for background job processing. This provides:
- Better performance and scalability
- More efficient resource usage
- Modern, actively maintained job processing system

## Requirements

### New Dependency: Redis

Sidekiq requires Redis to be running. Redis is a fast in-memory data store used for job queuing.

**For Docker users:** The docker-compose.yml files have been updated to include a Redis service automatically.

**For local/manual installations:**
1. Install Redis:
- Ubuntu/Debian: `sudo apt-get install redis-server`
- macOS: `brew install redis`
- Or download from: https://redis.io/download

2. Start Redis:
- Ubuntu/Debian: `sudo systemctl start redis-server`
- macOS: `brew services start redis`

3. Verify Redis is running: `redis-cli ping` (should respond with "PONG")

### Environment Variables

Set the `REDIS_URL` environment variable if Redis is not running on localhost:6379:
```bash
export REDIS_URL=redis://your-redis-host:6379/0
```

## Migration Steps

### 1. Update Dependencies
```bash
bundle install
```

### 2. Migrate Database (Optional)
The migration will drop the old `delayed_jobs` table which is no longer needed:
```bash
bundle exec rake db:migrate
```

### 3. Restart Workers
If you're running workers separately, restart them:
```bash
bundle exec rake seek:workers:restart
```

For Docker deployments, restart the seek_workers container:
```bash
docker-compose restart seek_workers
```

## What Stays the Same

- All rake tasks remain unchanged: `rake seek:workers:start`, `rake seek:workers:stop`, `rake seek:workers:restart`
- Admin interface for restarting workers remains the same
- Queue names and job priorities remain the same
- Job execution behavior remains the same (single retry, 24-hour timeout)

## Monitoring

### Sidekiq Web UI (Optional)

Sidekiq provides a web interface for monitoring jobs. To enable it, you can mount it in your routes.rb:

```ruby
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'
```

**Note:** Make sure to protect this route with authentication in production!

### Logs

Sidekiq logs are written to `log/sidekiq.log` (instead of the previous delayed_job logs).

### Checking Status

Check if Sidekiq is running:
```bash
bundle exec rake seek:workers:status
```

## Troubleshooting

### "Connection refused" errors
- Ensure Redis is running: `redis-cli ping`
- Check REDIS_URL environment variable is set correctly

### Jobs not processing
- Check Sidekiq is running: `bundle exec rake seek:workers:status`
- Check Sidekiq logs: `tail -f log/sidekiq.log`
- Check Redis is accessible: `redis-cli ping`

### Migration Issues
If you encounter issues with the migration:
1. Ensure all old delayed_job workers are stopped
2. Ensure Redis is running
3. Check the logs for specific error messages

## Rolling Back

If you need to roll back to delayed_job:
1. Restore the previous version of the code
2. Run `bundle install`
3. Restart the application and workers

Note: Any jobs that were queued in Redis will need to be re-queued.
12 changes: 6 additions & 6 deletions app/controllers/admin_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
require 'delayed/command'

class AdminController < ApplicationController
include CommonSweepers

Expand Down Expand Up @@ -381,9 +379,8 @@ def clear_cache
# give it up to 5 seconds to start up, otherwise the page reloads too quickly and says it is not running
def wait_for_delayed_job_to_start
sleep(0.5)
pid = Daemons::PidFile.new("#{Rails.root}/tmp/pids", 'delayed_job.0')
count = 0
while !pid.running? && (count < 10)
while !Seek::Workers.running? && (count < 10)
sleep(0.5)
count += 1
end
Expand Down Expand Up @@ -613,9 +610,12 @@ def array_remove_at(array, index)
return array.slice(0,index) + array.slice(index+1,array.length)
end

# this destroys any failed Delayed::Jobs
# this destroys any failed jobs
def clear_failed_jobs
Delayed::Job.where('failed_at IS NOT NULL').destroy_all
# Clear Sidekiq dead jobs
require 'sidekiq/api'
Sidekiq::DeadSet.new.clear
Sidekiq::RetrySet.new.clear
respond_to do |format|
format.json { head :ok }
end
Expand Down
2 changes: 1 addition & 1 deletion app/jobs/queue_names.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class QueueNames
DATAFILES = 'datafiles'.freeze
REMOTE_CONTENT = 'remotecontent'.freeze
AUTH_LOOKUP = 'authlookup'.freeze
DEFAULT = Delayed::Worker.default_queue_name
DEFAULT = 'default'.freeze
MAILERS = SEEK::Application.config.action_mailer.deliver_later_queue_name
INDEXING = 'indexing'.freeze
TEMPLATES = 'templates'.freeze
Expand Down
2 changes: 1 addition & 1 deletion config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class Application < Rails::Application

config.action_mailer.deliver_later_queue_name = 'mailers'

config.active_job.queue_adapter = :delayed_job
config.active_job.queue_adapter = :sidekiq

# Revert Rails 7 change that auto loads nested locale files
initializer :avoid_nested_locale_directories, before: :add_locales do
Expand Down
23 changes: 0 additions & 23 deletions config/initializers/delayed_job_config.rb

This file was deleted.

9 changes: 0 additions & 9 deletions config/initializers/seek_main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,5 @@
Annotations::Config.versioning_enabled = false

ENV['LANG'] = 'en_US.UTF-8'

begin
if ActiveRecord::Base.connection.data_source_exists?'delayed_jobs'
# OpenbisFakeJob.create_initial_jobs
# OpenbisGarbageJob.create_initial_jobs
end
rescue Exception=>e
Rails.logger.error "Error creating default delayed jobs - #{e.message}"
end
end
end
37 changes: 37 additions & 0 deletions config/initializers/sidekiq.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Sidekiq configuration
Sidekiq.configure_server do |config|
config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }

# Configure concurrency
config.concurrency = ENV.fetch('SIDEKIQ_CONCURRENCY', 5).to_i

# Set default error handler
config.error_handlers << lambda { |exception, context|
Rails.logger.error("Sidekiq error: #{exception.message}")
Rails.logger.error(exception.backtrace.join("\n"))
}
end

Sidekiq.configure_client do |config|
config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }
end

# Configure default Sidekiq options
Sidekiq.default_job_options = {
'backtrace' => true,
'retry' => false # Match the delayed_job behavior where max_attempts was 1
}

# Map queue names to priorities
# All queues have equal weight (2) as jobs are prioritized by the queue they're placed in
# rather than by priority weighting within Sidekiq
Sidekiq.options[:queues] = [
['default', 2],
['mailers', 2],
['authlookup', 2],
['remotecontent', 2],
['samples', 2],
['indexing', 2],
['templates', 2],
['datafiles', 2]
]
15 changes: 15 additions & 0 deletions config/sidekiq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
:concurrency: 5
:max_retries: 0
# Timeout for job execution (24 hours) - matches previous delayed_job max_run_time
:timeout: 86400

:queues:
- default
- mailers
- authlookup
- remotecontent
- samples
- indexing
- templates
- datafiles
10 changes: 10 additions & 0 deletions db/migrate/20251205000000_drop_delayed_jobs_table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class DropDelayedJobsTable < ActiveRecord::Migration[7.2]
def up
drop_table :delayed_jobs if table_exists?(:delayed_jobs)
end

def down
# Cannot recreate the table structure and data, migration is not reversible
raise ActiveRecord::IrreversibleMigration
end
end
14 changes: 13 additions & 1 deletion docker-compose-relative-root.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ x-shared:
RAILS_ENV: production
SOLR_PORT: 8983
SOLR_HOST: solr
REDIS_URL: redis://redis:6379/0
RAILS_LOG_LEVEL: info # debug, info, warn, error or fatal
RAILS_RELATIVE_URL_ROOT: '/seek'
env_file:
Expand All @@ -20,6 +21,8 @@ x-shared:
condition: service_healthy
solr:
condition: service_started
redis:
condition: service_started


services:
Expand Down Expand Up @@ -60,7 +63,7 @@ services:
start_period: 20s

seek_workers:
# The SEEK delayed job workers
# The SEEK background job workers (Sidekiq)
<<: *seek_base
container_name: seek-workers
environment:
Expand All @@ -82,6 +85,13 @@ services:
- seek
- /opt/solr/server/solr/configsets/seek_config

redis:
image: redis:7-alpine
container_name: seek-redis
restart: always
volumes:
- seek-redis-data:/data


volumes:
seek-filestore:
Expand All @@ -90,6 +100,8 @@ volumes:
external: true
seek-solr-data:
external: true
seek-redis-data:
external: true
seek-cache:
external: true
seek-assets:
Expand Down
13 changes: 12 additions & 1 deletion docker-compose-virtuoso.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ x-shared:
RAILS_ENV: production
SOLR_PORT: 8983
SOLR_HOST: solr
REDIS_URL: redis://redis:6379/0
RAILS_LOG_LEVEL: info # debug, info, warn, error or fatal
env_file:
- docker/db.env
Expand All @@ -20,6 +21,8 @@ x-shared:
condition: service_healthy
solr:
condition: service_started
redis:
condition: service_started
virtuoso:
condition: service_started

Expand Down Expand Up @@ -60,7 +63,7 @@ services:
start_period: 20s

seek_workers:
# The SEEK delayed job workers
# The SEEK background job workers (Sidekiq)
<<: *seek_base
container_name: seek-workers
environment:
Expand Down Expand Up @@ -94,10 +97,18 @@ services:
volumes:
- seek-virtuoso-data:/database

redis:
image: redis:7-alpine
container_name: seek-redis
restart: always
volumes:
- seek-redis-data:/data


volumes:
seek-filestore:
seek-mysql-db:
seek-solr-data:
seek-redis-data:
seek-cache:
seek-virtuoso-data:
Loading