diff options
Diffstat (limited to 'app/models/merge_request.rb')
-rw-r--r-- | app/models/merge_request.rb | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 82034f5946b..e96e26cc773 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -223,7 +223,13 @@ class MergeRequest < ApplicationRecord end def rebase_in_progress? - strong_memoize(:rebase_in_progress) do + (rebase_jid.present? && Gitlab::SidekiqStatus.running?(rebase_jid)) || + gitaly_rebase_in_progress? + end + + # TODO: remove the Gitaly lookup after v12.1, when rebase_jid will be reliable + def gitaly_rebase_in_progress? + strong_memoize(:gitaly_rebase_in_progress) do # The source project can be deleted next false unless source_project @@ -389,6 +395,26 @@ class MergeRequest < ApplicationRecord update_column(:merge_jid, jid) end + # Set off a rebase asynchronously, atomically updating the `rebase_jid` of + # the MR so that the status of the operation can be tracked. + def rebase_async(user_id) + transaction do + lock! + + raise ActiveRecord::StaleObjectError if !open? || rebase_in_progress? + + # Although there is a race between setting rebase_jid here and clearing it + # in the RebaseWorker, it can't do any harm since we check both that the + # attribute is set *and* that the sidekiq job is still running. So a JID + # for a completed RebaseWorker is equivalent to a nil JID. + jid = Sidekiq::Worker.skipping_transaction_check do + RebaseWorker.perform_async(id, user_id) + end + + update_column(:rebase_jid, jid) + end + end + def merge_participants participants = [author] @@ -1353,6 +1379,7 @@ class MergeRequest < ApplicationRecord end # TODO: remove once production database rename completes + # https://gitlab.com/gitlab-org/gitlab-ce/issues/47592 alias_attribute :allow_collaboration, :allow_maintainer_to_push def allow_collaboration |