Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#7934] Rework attachment masking uniqueness #7944

Merged
merged 2 commits into from
Oct 10, 2023
Merged
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
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ gem 'pg', '~> 1.5.4'
gem 'acts_as_versioned', git: 'https://github.com/mysociety/acts_as_versioned.git',
ref: '13e928b'
gem 'active_model_otp'
gem 'activejob-uniqueness'
gem 'bcrypt', '~> 3.1.19'
gem 'cancancan', '~> 3.5.0'
gem 'charlock_holmes', '~> 0.7.7'
Expand Down
6 changes: 0 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ GEM
activejob (7.0.8)
activesupport (= 7.0.8)
globalid (>= 0.3.6)
activejob-uniqueness (0.2.5)
activejob (>= 4.2, < 7.1)
redlock (>= 1.2, < 2)
activemodel (7.0.8)
activesupport (= 7.0.8)
activerecord (7.0.8)
Expand Down Expand Up @@ -422,8 +419,6 @@ GEM
recaptcha (5.15.0)
redcarpet (3.6.0)
redis (4.8.1)
redlock (1.3.2)
redis (>= 3.0.0, < 6.0)
regexp_parser (2.8.1)
representable (3.2.0)
declarative (< 0.1.0)
Expand Down Expand Up @@ -570,7 +565,6 @@ PLATFORMS

DEPENDENCIES
active_model_otp
activejob-uniqueness
acts_as_versioned!
alaveteli_features!
annotate (< 3.2.1)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/attachment_masks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def wait
)

else
FoiAttachmentMaskJob.perform_later(@attachment)
FoiAttachmentMaskJob.perform_once_later(@attachment)
end
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/attachments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def show
if @attachment.masked?
render body: @attachment.body, content_type: content_type
else
FoiAttachmentMaskJob.perform_later(@attachment)
FoiAttachmentMaskJob.perform_once_later(@attachment)

Timeout.timeout(5) do
until @attachment.masked?
Expand Down
3 changes: 2 additions & 1 deletion app/jobs/foi_attachment_mask_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
# FoiAttachmentMaskJob.perform(FoiAttachment.first)
#
class FoiAttachmentMaskJob < ApplicationJob
include Uniqueness

queue_as :default
unique :until_and_while_executing, on_conflict: :log

attr_reader :attachment

Expand Down
34 changes: 34 additions & 0 deletions app/jobs/foi_attachment_mask_job/uniqueness.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
##
# Module to add methods to check for existing jobs before performing/enqueuing
# attempting to ensure we execute once only.
#
# These methods only work if Sidekiq is used as the ActiveJob adapter.
#
module FoiAttachmentMaskJob::Uniqueness
def self.included(base)
base.extend ClassMethods
end

module ClassMethods

Check warning on line 12 in app/jobs/foi_attachment_mask_job/uniqueness.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Style/Documentation: Missing top-level documentation comment for module FoiAttachmentMaskJob::Uniqueness::ClassMethods. Raw Output: app/jobs/foi_attachment_mask_job/uniqueness.rb:12:3: C: Style/Documentation: Missing top-level documentation comment for module FoiAttachmentMaskJob::Uniqueness::ClassMethods. module ClassMethods ^^^^^^^^^^^^^^^^^^^
def perform_once_later(attachment)
perform_later(attachment) unless existing_job(attachment)
end

def perform_once_now(attachment)
existing_job(attachment)&.delete
perform_now(attachment)
end

def existing_job(attachment)
return unless queue_adapter.is_a?(
ActiveJob::QueueAdapters::SidekiqAdapter
)

queue = Sidekiq::Queue.new(queue_name)
queue.find do |j|
gid = j.display_args.first['_aj_globalid']
gid == attachment.to_gid.to_s
end
end
end
end
3 changes: 1 addition & 2 deletions app/models/foi_attachment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ def body
if masked?
@cached_body = file.download
elsif persisted?
FoiAttachmentMaskJob.unlock!(self)
FoiAttachmentMaskJob.perform_now(self)
FoiAttachmentMaskJob.perform_once_now(self)
reload
body
end
Expand Down
5 changes: 0 additions & 5 deletions config/initializers/active_job_uniqueness.rb

This file was deleted.

3 changes: 1 addition & 2 deletions lib/redis_connection.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
require File.expand_path('../config/load_env.rb', __dir__)

##
# Module to parse Redis ENV variables into usable configuration for Sidekiq and
# ActiveJob::Uniqueness gems.
# Module to parse Redis ENV variables into usable configuration for Sidekiq.
#
module RedisConnection
def self.instance
Expand Down
53 changes: 53 additions & 0 deletions spec/jobs/foi_attachment_mask_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,57 @@ def perform
expect(new_attachment.body).to include 'Banana'
end
end

describe '.perform_once_later' do
it 'call perform_later' do
expect(FoiAttachmentMaskJob).to receive(:perform_later)
FoiAttachmentMaskJob.perform_once_later(attachment)
end

it 'does not call perform_later if existing job is present' do
allow(FoiAttachmentMaskJob).to receive(:existing_job).and_return(double)
expect(FoiAttachmentMaskJob).to_not receive(:perform_later)
FoiAttachmentMaskJob.perform_once_later(attachment)
end
end

describe '.perform_once_now' do
it 'deleted existing job if present' do
job = double(:job)
allow(FoiAttachmentMaskJob).to receive(:existing_job).and_return(job)
expect(job).to receive(:delete)
FoiAttachmentMaskJob.perform_once_now(attachment)
end

it 'calls perform_now' do
expect(FoiAttachmentMaskJob).to receive(:perform_now)
FoiAttachmentMaskJob.perform_once_now(attachment)
end
end

describe '.existing_job' do
around do |example|
adapter = ActiveJob::Base.queue_adapter
ActiveJob::Base.queue_adapter = :sidekiq
example.call
ActiveJob::Base.queue_adapter = adapter
end

before do
allow(FoiAttachmentMaskJob).to receive(:queue_name).and_return('test')
end

after do
Sidekiq::Queue.new('test').clear
end

it 'return nil if existing job is not present' do
expect(FoiAttachmentMaskJob.existing_job(attachment)).to be_nil
end

it 'return existing job if present' do
FoiAttachmentMaskJob.perform_later(attachment)
expect(FoiAttachmentMaskJob.existing_job(attachment)).to_not be_nil
end
end
end
Loading