Class: MergeRequests::MergeabilityCheckService

Inherits:
BaseService
  • Object
show all
Includes:
Gitlab::ExclusiveLeaseHelpers, Gitlab::Utils::StrongMemoize
Defined in:
app/services/merge_requests/mergeability_check_service.rb

Constant Summary

Constants included from Gitlab::ExclusiveLeaseHelpers

Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError

Instance Attribute Summary

Attributes inherited from BaseService

#current_user, #params, #project

Instance Method Summary collapse

Methods included from Gitlab::ExclusiveLeaseHelpers

#in_lock

Methods included from Gitlab::Utils::StrongMemoize

#clear_memoization, #strong_memoize, #strong_memoized?

Methods included from BaseServiceUtility

#deny_visibility_level, #event_service, #log_error, #log_info, #notification_service, #system_hook_service, #todo_service, #visibility_level

Methods included from Gitlab::Allowable

#can?

Constructor Details

#initialize(merge_request) ⇒ MergeabilityCheckService

Returns a new instance of MergeabilityCheckService.


11
12
13
# File 'app/services/merge_requests/mergeability_check_service.rb', line 11

def initialize(merge_request)
  @merge_request = merge_request
end

Instance Method Details

#async_executeObject


15
16
17
18
19
20
# File 'app/services/merge_requests/mergeability_check_service.rb', line 15

def async_execute
  return service_error if service_error
  return unless merge_request.mark_as_checking

  MergeRequestMergeabilityCheckWorker.perform_async(merge_request.id)
end

#execute(recheck: false, retry_lease: true) ⇒ Object

Updates the MR merge_status. Whenever it switches to a can_be_merged state, the merge-ref is refreshed.

recheck - When given, it'll enforce a merge-ref refresh if the current merge_status is can_be_merged or cannot_be_merged and merge-ref is outdated. Given MergeRequests::RefreshService is called async, it might happen that the target branch gets updated, but the MergeRequest#merge_status lags behind. So in scenarios where we need the current state of the merge ref in repository, the `recheck` argument is required.

retry_lease - Concurrent calls wait for at least 10 seconds until the lease is granted (other process finishes running). Returns an error ServiceResponse if the lease is not granted during this time.

Returns a ServiceResponse indicating merge_status is/became can_be_merged and the merge-ref is synced. Success in case of being/becoming mergeable, error otherwise.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/services/merge_requests/mergeability_check_service.rb', line 39

def execute(recheck: false, retry_lease: true)
  return service_error if service_error
  return check_mergeability(recheck) unless merge_ref_auto_sync_lock_enabled?

  in_write_lock(retry_lease: retry_lease) do |retried|
    # When multiple calls are waiting for the same lock (retry_lease),
    # it's possible that when granted, the MR status was already updated for
    # that object, therefore we reset if there was a lease retry.
    merge_request.reset if retried

    check_mergeability(recheck)
  end
rescue FailedToObtainLockError => error
  ServiceResponse.error(message: error.message)
end