58 lines
2.2 KiB
Ruby
58 lines
2.2 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Gitlab
|
||
|
module Database
|
||
|
module Migrations
|
||
|
module LockRetriesHelpers
|
||
|
# Executes the block with a retry mechanism that alters the +lock_timeout+ and +sleep_time+ between attempts.
|
||
|
# The timings can be controlled via the +timing_configuration+ parameter.
|
||
|
# If the lock was not acquired within the retry period, a last attempt is made without using +lock_timeout+.
|
||
|
#
|
||
|
# Note this helper uses subtransactions when run inside an already open transaction.
|
||
|
#
|
||
|
# ==== Examples
|
||
|
# # Invoking without parameters
|
||
|
# with_lock_retries do
|
||
|
# drop_table :my_table
|
||
|
# end
|
||
|
#
|
||
|
# # Invoking with custom +timing_configuration+
|
||
|
# t = [
|
||
|
# [1.second, 1.second],
|
||
|
# [2.seconds, 2.seconds]
|
||
|
# ]
|
||
|
#
|
||
|
# with_lock_retries(timing_configuration: t) do
|
||
|
# drop_table :my_table # this will be retried twice
|
||
|
# end
|
||
|
#
|
||
|
# # Disabling the retries using an environment variable
|
||
|
# > export DISABLE_LOCK_RETRIES=true
|
||
|
#
|
||
|
# with_lock_retries do
|
||
|
# drop_table :my_table # one invocation, it will not retry at all
|
||
|
# end
|
||
|
#
|
||
|
# ==== Parameters
|
||
|
# * +timing_configuration+ - [[ActiveSupport::Duration, ActiveSupport::Duration], ...] lock timeout for the
|
||
|
# block, sleep time before the next iteration, defaults to
|
||
|
# `Gitlab::Database::WithLockRetries::DEFAULT_TIMING_CONFIGURATION`
|
||
|
# * +logger+ - [Gitlab::JsonLogger]
|
||
|
# * +env+ - [Hash] custom environment hash, see the example with `DISABLE_LOCK_RETRIES`
|
||
|
def with_lock_retries(*args, **kwargs, &block)
|
||
|
raise_on_exhaustion = !!kwargs.delete(:raise_on_exhaustion)
|
||
|
merged_args = {
|
||
|
connection: connection,
|
||
|
klass: self.class,
|
||
|
logger: Gitlab::BackgroundMigration::Logger,
|
||
|
allow_savepoints: true
|
||
|
}.merge(kwargs)
|
||
|
|
||
|
Gitlab::Database::WithLockRetries.new(**merged_args)
|
||
|
.run(raise_on_exhaustion: raise_on_exhaustion, &block)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|