From 28af97c6b48b76738757799a1a2aac85b63ae8fa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:40:54 +0000 Subject: [PATCH 1/5] Initial plan From 1ef9b049152d65f12cafb7d209effa06901fc34d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:48:04 +0000 Subject: [PATCH 2/5] Migrate ActiveJob adapter from delayed_job to sidekiq - Replace delayed_job_active_record with sidekiq and redis gems - Update ActiveJob queue adapter configuration - Create sidekiq initializer with Redis and queue configuration - Replace lib/seek/workers.rb to manage Sidekiq processes - Update queue_names.rb to remove Delayed::Worker dependency - Update admin controller to work with Sidekiq workers - Update Seek::Util helper methods for Sidekiq - Add Redis service to docker-compose.yml - Update docker worker startup script to tail sidekiq.log - Remove delayed_job_config.rb initializer Co-authored-by: fbacall <503373+fbacall@users.noreply.github.com> --- Gemfile | 4 +- app/controllers/admin_controller.rb | 5 +- app/jobs/queue_names.rb | 2 +- config/application.rb | 2 +- config/initializers/delayed_job_config.rb | 23 ------- config/initializers/sidekiq.rb | 36 +++++++++++ config/sidekiq.yml | 14 +++++ docker-compose.yml | 14 ++++- docker/start_workers.sh | 4 +- lib/seek/util.rb | 11 ++-- lib/seek/workers.rb | 75 ++++++++++++++++------- 11 files changed, 128 insertions(+), 62 deletions(-) delete mode 100644 config/initializers/delayed_job_config.rb create mode 100644 config/initializers/sidekiq.rb create mode 100644 config/sidekiq.yml diff --git a/Gemfile b/Gemfile index 7c4250d7d2..eeacc08efd 100644 --- a/Gemfile +++ b/Gemfile @@ -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' diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 42cf82ea97..2d2058921c 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -1,5 +1,3 @@ -require 'delayed/command' - class AdminController < ApplicationController include CommonSweepers @@ -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 diff --git a/app/jobs/queue_names.rb b/app/jobs/queue_names.rb index 1da5f863db..3efa02b573 100644 --- a/app/jobs/queue_names.rb +++ b/app/jobs/queue_names.rb @@ -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 diff --git a/config/application.rb b/config/application.rb index 72a7a13617..5b3f59b160 100644 --- a/config/application.rb +++ b/config/application.rb @@ -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 diff --git a/config/initializers/delayed_job_config.rb b/config/initializers/delayed_job_config.rb deleted file mode 100644 index 52de0b551e..0000000000 --- a/config/initializers/delayed_job_config.rb +++ /dev/null @@ -1,23 +0,0 @@ -# Try and avoid deadlocks -Delayed::Backend::ActiveRecord.configure do |config| - config.reserve_sql_strategy = :default_sql -end - -SEEK::Application.configure do - - Delayed::Worker.destroy_failed_jobs = false - if Rails.env.development? - Delayed::Worker.sleep_delay = 45 - else - Delayed::Worker.sleep_delay = 3 - end - - Delayed::Worker.max_attempts = 1 - Delayed::Worker.max_run_time = 1.day - Delayed::Worker.read_ahead = 20 - Delayed::Worker.backend = :active_record - Delayed::Worker.default_queue_name = 'default' - - #Delayed::Worker.logger = Delayed::Worker.logger = ActiveSupport::BufferedLogger.new(Rails.root.join('log/worker.log'),Logger::INFO) - #Delayed::Worker.logger.auto_flushing = 1 -end diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb new file mode 100644 index 0000000000..f10e0a1887 --- /dev/null +++ b/config/initializers/sidekiq.rb @@ -0,0 +1,36 @@ +# 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 +# Higher weight = higher priority +Sidekiq.options[:queues] = [ + ['default', 2], + ['mailers', 2], + ['authlookup', 2], + ['remotecontent', 2], + ['samples', 2], + ['indexing', 2], + ['templates', 2], + ['datafiles', 2] +] diff --git a/config/sidekiq.yml b/config/sidekiq.yml new file mode 100644 index 0000000000..4decf185b4 --- /dev/null +++ b/config/sidekiq.yml @@ -0,0 +1,14 @@ +--- +:concurrency: 5 +:max_retries: 0 +:timeout: 86400 + +:queues: + - default + - mailers + - authlookup + - remotecontent + - samples + - indexing + - templates + - datafiles diff --git a/docker-compose.yml b/docker-compose.yml index 169fb2c8b8..d17163cd85 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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 @@ -19,6 +20,8 @@ x-shared: condition: service_healthy solr: condition: service_started + redis: + condition: service_started services: @@ -59,7 +62,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: @@ -81,6 +84,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: external: true @@ -88,5 +98,7 @@ volumes: external: true seek-solr-data: external: true + seek-redis-data: + external: true seek-cache: external: true diff --git a/docker/start_workers.sh b/docker/start_workers.sh index 42e7f1e005..d664eea768 100644 --- a/docker/start_workers.sh +++ b/docker/start_workers.sh @@ -17,9 +17,9 @@ echo "STARTING WORKERS" bundle exec rake seek:workers:start # Ensure the workers have started up and the logs are available before tailing -while [ ! -f log/production.log ] +while [ ! -f log/sidekiq.log ] do sleep 0.2 done -tail -f log/production.log +tail -f log/sidekiq.log diff --git a/lib/seek/util.rb b/lib/seek/util.rb index 749c91b294..8ccb62e6bc 100644 --- a/lib/seek/util.rb +++ b/lib/seek/util.rb @@ -140,12 +140,13 @@ def self.database_type ActiveRecord::Base.connection.instance_values['config'][:adapter] end + def self.background_job_pids + Seek::Workers.pids + end + + # Alias for backwards compatibility def self.delayed_job_pids - directory = "#{Rails.root}/tmp/pids" - Daemons::PidFile.find_files(directory, 'delayed_job', false, '').collect do |path| - file = path.sub("#{directory}/", '').sub('.pid', '') - Daemons::PidFile.new(directory, file) - end + background_job_pids end # Use this to avoid needlessly regenerating the url helper module each time a route needs to be accessed diff --git a/lib/seek/workers.rb b/lib/seek/workers.rb index 354f78a792..c10037c741 100644 --- a/lib/seek/workers.rb +++ b/lib/seek/workers.rb @@ -1,24 +1,18 @@ -require 'delayed/command' - -# module for handling interaction with delayed job workers +# module for handling interaction with Sidekiq workers module Seek module Workers + SIDEKIQ_PID_FILE = "#{Rails.root}/tmp/pids/sidekiq.pid".freeze + def self.start - commands = create_commands('start') - daemonize_commands(commands) - end - - def self.daemonize_commands(commands) - commands.map { |command| Delayed::Command.new(command.split).daemonize } - end - - def self.create_commands(action) - commands = [] - - active_queues.each_with_index do |queue_name, index| - commands << command(queue_name, index + 1, 1, action) - end - commands + return if running? + + queues = active_queues.join(',') + command = "bundle exec sidekiq -d -e #{Rails.env} " \ + "-C config/sidekiq.yml " \ + "-P #{SIDEKIQ_PID_FILE} " \ + "-L #{Rails.root}/log/sidekiq.log" + + system(command) end def self.active_queues @@ -34,21 +28,56 @@ def self.active_queues end def self.stop - # will stop the first 15, not expecting more than that - daemonize_commands(['stop -n 15']) + if File.exist?(SIDEKIQ_PID_FILE) + pid = File.read(SIDEKIQ_PID_FILE).to_i + begin + Process.kill('TERM', pid) + # Wait for graceful shutdown + 10.times do + sleep(1) + break unless process_running?(pid) + end + # Force kill if still running + Process.kill('KILL', pid) if process_running?(pid) + rescue Errno::ESRCH + # Process doesn't exist + end + File.delete(SIDEKIQ_PID_FILE) if File.exist?(SIDEKIQ_PID_FILE) + end end def self.status - daemonize_commands(['status']) + if running? + puts "Sidekiq is running (PID: #{File.read(SIDEKIQ_PID_FILE).strip})" + else + puts "Sidekiq is not running" + end end def self.restart stop + sleep(1) start end - def self.command(queue_name, index, number_of_workers, action) - "--queue=#{queue_name} -i #{index} -n #{number_of_workers} #{action}" + def self.running? + if File.exist?(SIDEKIQ_PID_FILE) + pid = File.read(SIDEKIQ_PID_FILE).to_i + process_running?(pid) + else + false + end + end + + def self.process_running?(pid) + Process.kill(0, pid) + true + rescue Errno::ESRCH, Errno::EPERM + false + end + + def self.pids + running? ? [File.read(SIDEKIQ_PID_FILE).to_i] : [] end end end From 34e57d251a34572e9da35a6486d1ba8ac968b268 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:50:39 +0000 Subject: [PATCH 3/5] Update tests and remaining references from delayed_job to sidekiq - Update admin controller tests to reference background job workers - Update clear_failed_jobs to use Sidekiq API instead of ActiveRecord - Remove obsolete delayed_jobs table check from seek_main.rb - Add Redis service to docker-compose-virtuoso.yml - Add Redis service to docker-compose-relative-root.yml Co-authored-by: fbacall <503373+fbacall@users.noreply.github.com> --- app/controllers/admin_controller.rb | 7 +++++-- config/initializers/seek_main.rb | 9 --------- docker-compose-relative-root.yml | 14 +++++++++++++- docker-compose-virtuoso.yml | 13 ++++++++++++- test/functional/admin_controller_test.rb | 4 ++-- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 2d2058921c..e9c5c2d1c0 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -610,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 diff --git a/config/initializers/seek_main.rb b/config/initializers/seek_main.rb index 858b49d4cf..1d06666e31 100644 --- a/config/initializers/seek_main.rb +++ b/config/initializers/seek_main.rb @@ -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 diff --git a/docker-compose-relative-root.yml b/docker-compose-relative-root.yml index 809bd76191..cccd6dfff3 100644 --- a/docker-compose-relative-root.yml +++ b/docker-compose-relative-root.yml @@ -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: @@ -20,6 +21,8 @@ x-shared: condition: service_healthy solr: condition: service_started + redis: + condition: service_started services: @@ -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: @@ -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: @@ -90,6 +100,8 @@ volumes: external: true seek-solr-data: external: true + seek-redis-data: + external: true seek-cache: external: true seek-assets: diff --git a/docker-compose-virtuoso.yml b/docker-compose-virtuoso.yml index d6e19a002d..8ff2641f3e 100644 --- a/docker-compose-virtuoso.yml +++ b/docker-compose-virtuoso.yml @@ -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 @@ -20,6 +21,8 @@ x-shared: condition: service_healthy solr: condition: service_started + redis: + condition: service_started virtuoso: condition: service_started @@ -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: @@ -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: diff --git a/test/functional/admin_controller_test.rb b/test/functional/admin_controller_test.rb index f342837174..61e4f34c05 100644 --- a/test/functional/admin_controller_test.rb +++ b/test/functional/admin_controller_test.rb @@ -30,13 +30,13 @@ def setup assert_response :success end - test 'non admin cannot restart the delayed job' do + test 'non admin cannot restart the background job workers' do login_as(FactoryBot.create(:user)) post :restart_delayed_job refute_nil flash[:error] end - test 'admin can restart the delayed job' do + test 'admin can restart the background job workers' do post :restart_delayed_job assert_nil flash[:error] end From 123ce4b5123191d355349f3303035252cc0fc6c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:52:12 +0000 Subject: [PATCH 4/5] Address code review feedback - Add Errno::EINVAL to exception handling in process_running? - Extract PID file reading logic into private method to reduce duplication - Add comment explaining 24-hour timeout value in sidekiq.yml - Add comment explaining equal queue weights in sidekiq initializer Co-authored-by: fbacall <503373+fbacall@users.noreply.github.com> --- config/initializers/sidekiq.rb | 3 ++- config/sidekiq.yml | 1 + lib/seek/workers.rb | 14 ++++++++++---- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index f10e0a1887..6313409062 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -23,7 +23,8 @@ } # Map queue names to priorities -# Higher weight = higher priority +# 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], diff --git a/config/sidekiq.yml b/config/sidekiq.yml index 4decf185b4..3464be5809 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -1,6 +1,7 @@ --- :concurrency: 5 :max_retries: 0 +# Timeout for job execution (24 hours) - matches previous delayed_job max_run_time :timeout: 86400 :queues: diff --git a/lib/seek/workers.rb b/lib/seek/workers.rb index c10037c741..1363033443 100644 --- a/lib/seek/workers.rb +++ b/lib/seek/workers.rb @@ -29,7 +29,7 @@ def self.active_queues def self.stop if File.exist?(SIDEKIQ_PID_FILE) - pid = File.read(SIDEKIQ_PID_FILE).to_i + pid = read_pid begin Process.kill('TERM', pid) # Wait for graceful shutdown @@ -62,7 +62,7 @@ def self.restart def self.running? if File.exist?(SIDEKIQ_PID_FILE) - pid = File.read(SIDEKIQ_PID_FILE).to_i + pid = read_pid process_running?(pid) else false @@ -72,12 +72,18 @@ def self.running? def self.process_running?(pid) Process.kill(0, pid) true - rescue Errno::ESRCH, Errno::EPERM + rescue Errno::ESRCH, Errno::EPERM, Errno::EINVAL false end def self.pids - running? ? [File.read(SIDEKIQ_PID_FILE).to_i] : [] + running? ? [read_pid] : [] + end + + private + + def self.read_pid + File.read(SIDEKIQ_PID_FILE).to_i end end end From f71e15a31360ca6be84ea3d2ac5362d8693e42e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:55:20 +0000 Subject: [PATCH 5/5] Add migration to drop delayed_jobs table and documentation - Create migration to drop delayed_jobs table - Add comprehensive migration notes for users upgrading to Sidekiq - Document Redis requirements and setup steps - Document troubleshooting and rollback procedures Co-authored-by: fbacall <503373+fbacall@users.noreply.github.com> --- MIGRATION_NOTES_SIDEKIQ.md | 118 ++++++++++++++++++ .../20251205000000_drop_delayed_jobs_table.rb | 10 ++ 2 files changed, 128 insertions(+) create mode 100644 MIGRATION_NOTES_SIDEKIQ.md create mode 100644 db/migrate/20251205000000_drop_delayed_jobs_table.rb diff --git a/MIGRATION_NOTES_SIDEKIQ.md b/MIGRATION_NOTES_SIDEKIQ.md new file mode 100644 index 0000000000..c6008b3a3d --- /dev/null +++ b/MIGRATION_NOTES_SIDEKIQ.md @@ -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. diff --git a/db/migrate/20251205000000_drop_delayed_jobs_table.rb b/db/migrate/20251205000000_drop_delayed_jobs_table.rb new file mode 100644 index 0000000000..cbecd1a531 --- /dev/null +++ b/db/migrate/20251205000000_drop_delayed_jobs_table.rb @@ -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