ActiveJobLock enhancements (cleanup and Delayed::Job destroy sync)
This commit is contained in:
parent
ff6b4256e1
commit
4c9919a23e
8 changed files with 119 additions and 0 deletions
7
app/jobs/active_job_lock_cleanup_job.rb
Normal file
7
app/jobs/active_job_lock_cleanup_job.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class ActiveJobLockCleanupJob < ApplicationJob
|
||||
include HasActiveJobLock
|
||||
|
||||
def perform(diff = 1.day)
|
||||
::ActiveJobLock.where('created_at < ?', Time.zone.now - diff).destroy_all
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
require 'delayed_job'
|
||||
|
||||
module Delayed
|
||||
class Job < ::ActiveRecord::Base
|
||||
|
||||
after_destroy :remove_active_job_lock
|
||||
|
||||
def remove_active_job_lock
|
||||
# only ActiveJob Delayed::Jobs can have a lock
|
||||
return if !payload_object.is_a?(::ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper)
|
||||
|
||||
# deserialize ActiveJob and load it's arguments to generate the lock_key
|
||||
active_job = ::ActiveJob::Base.deserialize(payload_object.job_data)
|
||||
active_job.arguments = ::ActiveJob::Arguments.deserialize(active_job.instance_variable_get(:@serialized_arguments))
|
||||
|
||||
# remove possible lock
|
||||
active_job.try(:release_active_job_lock!)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class ActiveJobLockCleanupJobScheduler < ActiveRecord::Migration[5.2]
|
||||
def up
|
||||
return if !Setting.find_by(name: 'system_init_done')
|
||||
|
||||
Scheduler.create_or_update(
|
||||
name: 'Cleanup ActiveJob locks.',
|
||||
method: 'ActiveJobLockCleanupJob.perform_now',
|
||||
period: 1.day,
|
||||
prio: 2,
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
end
|
||||
end
|
|
@ -127,6 +127,15 @@ Scheduler.create_or_update(
|
|||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Scheduler.create_or_update(
|
||||
name: 'Cleanup ActiveJob locks.',
|
||||
method: 'ActiveJobLockCleanupJob.perform_now',
|
||||
period: 1.day,
|
||||
prio: 2,
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Scheduler.create_or_update(
|
||||
name: 'Sync calendars with ical feeds.',
|
||||
method: 'Calendar.sync',
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActiveJobLockCleanupJobScheduler, type: :db_migration do
|
||||
|
||||
let(:scheduler_method) { 'ActiveJobLockCleanupJob.perform_now' }
|
||||
|
||||
context 'New system', system_init_done: false do
|
||||
it 'has no work to do' do
|
||||
expect { migrate }.not_to change { Scheduler.exists?(method: scheduler_method) }.from(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'System that is already set up' do
|
||||
|
||||
before do
|
||||
Scheduler.find_by(method: scheduler_method).destroy!
|
||||
end
|
||||
|
||||
it 'creates Scheduler' do
|
||||
expect { migrate }.to change { Scheduler.exists?(method: scheduler_method) }
|
||||
end
|
||||
end
|
||||
end
|
27
spec/jobs/active_job_lock_cleanup_job_spec.rb
Normal file
27
spec/jobs/active_job_lock_cleanup_job_spec.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActiveJobLockCleanupJob, type: :job do
|
||||
|
||||
context 'when ActiveJobLock records older than a day are present' do
|
||||
|
||||
before do
|
||||
create(:active_job_lock, created_at: 1.day.ago)
|
||||
travel 1.minute
|
||||
end
|
||||
|
||||
it 'cleans up those jobs' do
|
||||
expect { described_class.perform_now }.to change(ActiveJobLock, :count).by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when recent ActiveJobLock records are present' do
|
||||
|
||||
before do
|
||||
create(:active_job_lock, created_at: 1.minute.ago)
|
||||
end
|
||||
|
||||
it 'keeps those jobs' do
|
||||
expect { described_class.perform_now }.not_to change(ActiveJobLock, :count)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -80,6 +80,23 @@ RSpec.describe HasActiveJobLock, type: :job do
|
|||
it 'allows execution of perform_now jobs' do
|
||||
expect { job_class.perform_now }.to change(job_class, :perform_counter).by(1)
|
||||
end
|
||||
|
||||
context 'when Delayed::Job gets destroyed' do
|
||||
|
||||
before do
|
||||
::ActiveJob::Base.queue_adapter = :delayed_job
|
||||
end
|
||||
|
||||
it 'is ensured that ActiveJobLock gets removed' do
|
||||
job = job_class.perform_later
|
||||
|
||||
expect do
|
||||
Delayed::Job.find(job.provider_job_id).destroy!
|
||||
end.to change {
|
||||
ActiveJobLock.exists?(lock_key: job.lock_key, active_job_id: job.job_id)
|
||||
}.to(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'dynamic lock key' do
|
||||
|
|
|
@ -33,6 +33,7 @@ RSpec.configure do |config|
|
|||
|
||||
example.run
|
||||
|
||||
ensure
|
||||
::ActiveJob::Base.queue_adapter = default_queue_adapter
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue