Skip to content

Commit

Permalink
Constrain VirusScanWorker to a single job per asset
Browse files Browse the repository at this point in the history
This will prevent multiple jobs becoming enqueued for a single asset
until the original job has finished executing.

We are currently seeing an issue where a user can replace the file after
uploading but before the virus scan has completed. This results in a
second virus scan being enqueued, which subsequently fails as the asset
has been deleted from the filesystem. This will prevent that from
happening.
  • Loading branch information
brucebolt committed Dec 7, 2023
1 parent 1cdc545 commit d0451ad
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
2 changes: 2 additions & 0 deletions app/workers/virus_scan_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
class VirusScanWorker
include Sidekiq::Worker

sidekiq_options lock: :until_and_while_executing

def perform(asset_id)
asset = Asset.find(asset_id)
if asset.unscanned?
Expand Down
10 changes: 10 additions & 0 deletions spec/workers/virus_scan_worker_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "rails_helper"
require "services"
require "sidekiq_unique_jobs/testing"

RSpec.describe VirusScanWorker do
let(:worker) { described_class.new }
Expand All @@ -10,6 +11,15 @@
allow(Services).to receive(:virus_scanner).and_return(scanner)
end

specify { expect(described_class).to have_valid_sidekiq_options }

it "does not permit multiple jobs to be enqueued for the same asset" do
SidekiqUniqueJobs.use_config(enabled: true) do
expect { described_class.perform_in(1.minute, asset.id.to_s) }.to enqueue_sidekiq_job(described_class)
expect { described_class.perform_in(1.minute, asset.id.to_s) }.not_to enqueue_sidekiq_job(described_class)
end
end

it "calls out to the VirusScanner to scan the file" do
expect(scanner).to receive(:scan).with(asset.file.path)

Expand Down

0 comments on commit d0451ad

Please sign in to comment.