Commit cc387763 authored by Alex Kalderimis's avatar Alex Kalderimis

Ensure that new-version workers are run correctly

Workers need to be enqueued outside of transactions, so we use
`run_after_commit` to arrange for this.
parent 82b9cf7b
...@@ -4,6 +4,7 @@ module DesignManagement ...@@ -4,6 +4,7 @@ module DesignManagement
class Version < ApplicationRecord class Version < ApplicationRecord
include Importable include Importable
include ShaAttribute include ShaAttribute
include AfterCommitQueue
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
extend Gitlab::ExclusiveLeaseHelpers extend Gitlab::ExclusiveLeaseHelpers
......
...@@ -16,10 +16,6 @@ module DesignManagement ...@@ -16,10 +16,6 @@ module DesignManagement
version = delete_designs! version = delete_designs!
version.run_after_commit do
::DesignManagement::NewVersionWorker.perform_async(version.id)
end
# Create a Geo event so changes will be replicated to secondary node(s) # Create a Geo event so changes will be replicated to secondary node(s)
repository.log_geo_updated_event repository.log_geo_updated_event
......
...@@ -17,7 +17,17 @@ module DesignManagement ...@@ -17,7 +17,17 @@ module DesignManagement
message: commit_message, message: commit_message,
actions: actions.map(&:gitaly_action)) actions: actions.map(&:gitaly_action))
::DesignManagement::Version.create_for_designs(actions, sha, current_user) ::DesignManagement::Version
.create_for_designs(actions, sha, current_user)
.tap { |version| post_process(version) }
end
private
def post_process(version)
version.run_after_commit_or_now do
::DesignManagement::NewVersionWorker.perform_async(id)
end
end end
end end
end end
...@@ -19,13 +19,13 @@ module DesignManagement ...@@ -19,13 +19,13 @@ module DesignManagement
repository.create_if_not_exists repository.create_if_not_exists
uploaded_designs = upload_designs! uploaded_designs, version = upload_designs!
skipped_designs = designs - uploaded_designs skipped_designs = designs - uploaded_designs
# Create a Geo event so changes will be replicated to secondary node(s) # Create a Geo event so changes will be replicated to secondary node(s)
repository.log_geo_updated_event repository.log_geo_updated_event
success({ designs: uploaded_designs, skipped_designs: skipped_designs }) success({ designs: uploaded_designs, version: version, skipped_designs: skipped_designs })
rescue ::ActiveRecord::RecordInvalid => e rescue ::ActiveRecord::RecordInvalid => e
error(e.message) error(e.message)
end end
...@@ -35,25 +35,11 @@ module DesignManagement ...@@ -35,25 +35,11 @@ module DesignManagement
attr_reader :files attr_reader :files
def upload_designs! def upload_designs!
# puts "Waiting [#{Thread.current.object_id}]" ::DesignManagement::Version.lock_for_creation(project.id) do
actions = ::DesignManagement::Version.lock_for_creation(project.id) do
# puts ". Building [#{Thread.current.object_id}]"
actions = build_actions actions = build_actions
# if actions.empty?
# puts ".. Skipping [#{Thread.current.object_id}]"
# else
if actions.present?
# puts ".. Running [#{Thread.current.object_id}]"
version = run_actions(actions)
version.run_after_commit do
::DesignManagement::NewVersionWorker.perform_async(version.id)
end
end
actions [actions.map(&:design), actions.presence && run_actions(actions)]
end end
# puts "Done [#{Thread.current.object_id}]"
actions.map(&:design)
end end
# Returns `Design` instances that correspond with `files`. # Returns `Design` instances that correspond with `files`.
......
...@@ -91,6 +91,12 @@ describe DesignManagement::DeleteDesignsService do ...@@ -91,6 +91,12 @@ describe DesignManagement::DeleteDesignsService do
expect { run_service }.to change { counter.read(:delete) }.by(1) expect { run_service }.to change { counter.read(:delete) }.by(1)
end end
it 'informs the new-version-worker' do
expect(::DesignManagement::NewVersionWorker).to receive(:perform_async).with(Integer)
run_service
end
it 'creates a new verison' do it 'creates a new verison' do
expect { run_service }.to change { DesignManagement::Version.where(issue: issue).count }.by(1) expect { run_service }.to change { DesignManagement::Version.where(issue: issue).count }.by(1)
end end
......
...@@ -20,18 +20,7 @@ describe DesignManagement::SaveDesignsService do ...@@ -20,18 +20,7 @@ describe DesignManagement::SaveDesignsService do
before do before do
project.add_developer(developer) project.add_developer(developer)
# allow(::DesignManagement::NewVersionWorker).to receive(:perform_async)
allow(::DesignManagement::NewVersionWorker).to receive(:perform_async)
end
RSpec::Matchers.define :enqueue_worker do
match do |action|
expect(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).once.with(Integer)
action.call
end
supports_block_expectations
end end
def run_service(files_to_upload = nil) def run_service(files_to_upload = nil)
...@@ -237,7 +226,10 @@ describe DesignManagement::SaveDesignsService do ...@@ -237,7 +226,10 @@ describe DesignManagement::SaveDesignsService do
end end
it 'enqueues just one new version worker' do it 'enqueues just one new version worker' do
expect { run_service }.to enqueue_worker expect(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).once.with(Integer)
run_service
end end
end end
...@@ -260,7 +252,10 @@ describe DesignManagement::SaveDesignsService do ...@@ -260,7 +252,10 @@ describe DesignManagement::SaveDesignsService do
end end
it 'enqueues a new version worker' do it 'enqueues a new version worker' do
expect { run_service }.to enqueue_worker expect(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).once.with(Integer)
run_service
end end
it 'creates a single commit' do it 'creates a single commit' do
...@@ -272,7 +267,8 @@ describe DesignManagement::SaveDesignsService do ...@@ -272,7 +267,8 @@ describe DesignManagement::SaveDesignsService do
expect { run_service }.to change { commit_count.call }.by(1) expect { run_service }.to change { commit_count.call }.by(1)
end end
it 'only does 4 gitaly calls', :request_store, :sidekiq_might_not_need_inline do it 'only does 5 gitaly calls', :request_store, :sidekiq_might_not_need_inline do
allow(::DesignManagement::NewVersionWorker).to receive(:perform_async).with(Integer)
service = described_class.new(project, user, issue: issue, files: files) service = described_class.new(project, user, issue: issue, files: files)
# Some unrelated calls that are usually cached or happen only once # Some unrelated calls that are usually cached or happen only once
service.__send__(:repository).create_if_not_exists service.__send__(:repository).create_if_not_exists
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment