Skip to content

Commit

Permalink
create child job class to use new Sidekiq queue
Browse files Browse the repository at this point in the history
There is no way to reassign a job to another queue once it has been
created. To use the new :resource_intensive Sidekiq queue, we need a
separate job class that is configured to use that queue.

Enter CreateLargeDerivativesJob.

It functions exactly the same as CreateDerivativesJob, except that it
queues into the :resource_intensive queue and has a higher priority.
This way, we can have two separate job classes with different Sidekiq
configurations while using the same application logic for both.
  • Loading branch information
bkiahstroud committed Jan 4, 2024
1 parent ab95c9a commit cceb544
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 7 deletions.
12 changes: 5 additions & 7 deletions app/jobs/create_derivatives_job_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# frozen_string_literal: true

module CreateDerivativesJobDecorator
def self.prepended(base)
base.class_eval do
before_perform :reassign_queue, if: ->() { arguments.first.video? || arguments.first.audio? }
end
end
def perform(file_set, file_id, filepath = nil)
return super if self.is_a?(CreateLargeDerivativesJob)
return super unless file_set.video? || file_set.audio?

def reassign_queue
self.queue_name = 'resource_intensive'
CreateLargeDerivativesJob.perform_later(*self.arguments)
true
end
end

Expand Down
6 changes: 6 additions & 0 deletions app/jobs/create_large_derivatives_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

class CreateLargeDerivativesJob < CreateDerivativesJob
queue_as :resource_intensive
queue_with_priority 20 # TODO: necessary?
end
79 changes: 79 additions & 0 deletions spec/jobs/create_derivatives_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# frozen_string_literal: true

RSpec.describe CreateDerivativesJob do
around do |example|
ffmpeg_enabled = Hyrax.config.enable_ffmpeg
Hyrax.config.enable_ffmpeg = true
example.run
Hyrax.config.enable_ffmpeg = ffmpeg_enabled
end

describe 'recreating self as a CreateLargeDerivativesJob' do
let(:id) { '123' }
let(:file_set) { FileSet.new }
let(:file) do
Hydra::PCDM::File.new.tap do |f|
f.content = 'foo'
f.original_name = filename
f.save!
end
end

before do
allow(FileSet).to receive(:find).with(id).and_return(file_set)
allow(file_set).to receive(:mime_type).and_return(mime_type)
allow(file_set).to receive(:id).and_return(id)
# Short-circuit irrelevant logic
allow(file_set).to receive(:reload)
allow(file_set).to receive(:update_index)
end

context 'with an image file' do
let(:mime_type) { 'image/jpeg' }
let(:filename) { 'picture.jpg' }

before do
# Short-circuit irrelevant logic
allow(Hydra::Derivatives::ImageDerivatives).to receive(:create)
end

it 'does not recreate as a CreateLargeDerivativesJob' do
expect(CreateLargeDerivativesJob).not_to receive(:perform_later)

described_class.perform_now(file_set, file.id)
end
end

context 'with an video file' do
let(:mime_type) { 'video/mp4' }
let(:filename) { 'video.mp4' }

before do
# Short-circuit irrelevant logic
allow(Hydra::Derivatives::VideoDerivatives).to receive(:create)
end

it 'recreates as a CreateLargeDerivativesJob' do
expect(CreateLargeDerivativesJob).to receive(:perform_later)

described_class.perform_now(file_set, file.id)
end
end

context 'with an audio file' do
let(:mime_type) { 'audio/x-wav' }
let(:filename) { 'audio.wav' }

before do
# Short-circuit irrelevant logic
allow(Hydra::Derivatives::AudioDerivatives).to receive(:create)
end

it 'recreates as a CreateLargeDerivativesJob' do
expect(CreateLargeDerivativesJob).to receive(:perform_later)

described_class.perform_now(file_set, file.id)
end
end
end
end
41 changes: 41 additions & 0 deletions spec/jobs/create_large_derivatives_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

RSpec.describe CreateLargeDerivativesJob, type: :job do
let(:id) { '123' }
let(:file_set) { FileSet.new }
let(:file) do
Hydra::PCDM::File.new.tap do |f|
f.content = 'foo'
f.original_name = 'video.mp4'
f.save!
end
end

before do
allow(FileSet).to receive(:find).with(id).and_return(file_set)
allow(file_set).to receive(:id).and_return(id)
# Short-circuit irrelevant logic
allow(file_set).to receive(:reload)
allow(file_set).to receive(:update_index)
end

it 'runs in the :resource_intensive queue' do
expect { described_class.perform_later(file_set, file.id) }
.to have_enqueued_job(described_class)
.on_queue('resource_intensive')
end

# @see CreateDerivativesJobDecorator#perform
it "doesn't schedule itself infinitly" do
expect(described_class).not_to receive(:perform_later)

described_class.perform_now(file_set, file.id)
end

it 'successfully calls the logic in CreateDerivativesJob' do
allow(file_set).to receive(:mime_type).and_return('video/mp4')
expect(Hydra::Derivatives::VideoDerivatives).to receive(:create)

described_class.perform_now(file_set, file.id)
end
end

0 comments on commit cceb544

Please sign in to comment.