mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-16 15:57:22 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "active_record"
|
||||
require_relative "gitlab_patches/abstract_adapter"
|
||||
require_relative "gitlab_patches/attribute_methods"
|
||||
require_relative "gitlab_patches/version"
|
||||
require_relative "gitlab_patches/rescue_from"
|
||||
require_relative "gitlab_patches/relation/find_or_create_by"
|
||||
|
@ -0,0 +1,103 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
if defined?(Gitlab) && ActiveRecord.version.to_s != '7.1.5.1'
|
||||
raise "This patch is only needed in Rails 7.1.5.1 for https://github.com/rails/rails/issues/51780"
|
||||
end
|
||||
|
||||
# rubocop:disable Lint/RescueException -- This is copied directly from Rails.
|
||||
# rubocop:disable Lint/AmbiguousOperatorPrecedence -- This is a Rails patch.
|
||||
# rubocop:disable Naming/RescuedExceptionsVariableName -- This is a Rails patch.
|
||||
# rubocop:disable Style/NumericPredicate -- This is a Rails patch.
|
||||
# rubocop:disable Cop/AvoidReturnFromBlocks -- This is a Rails patch.
|
||||
# rubocop:disable Style/RescueStandardError -- This is a Rails patch.
|
||||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
class AbstractAdapter
|
||||
# Add the new method that wraps configure_connection with exception handling
|
||||
def attempt_configure_connection
|
||||
configure_connection
|
||||
rescue Exception # Need to handle things such as Timeout::ExitException
|
||||
disconnect!
|
||||
raise
|
||||
end
|
||||
|
||||
# Disconnects from the database if already connected, and establishes a new
|
||||
# connection with the database. Implementors should define private #reconnect
|
||||
# instead.
|
||||
def reconnect!(restore_transactions: false)
|
||||
retries_available = connection_retries
|
||||
deadline = retry_deadline && Process.clock_gettime(Process::CLOCK_MONOTONIC) + retry_deadline
|
||||
|
||||
@lock.synchronize do
|
||||
reconnect
|
||||
|
||||
enable_lazy_transactions!
|
||||
@raw_connection_dirty = false
|
||||
@verified = true
|
||||
|
||||
reset_transaction(restore: restore_transactions) do
|
||||
clear_cache!(new_connection: true)
|
||||
attempt_configure_connection
|
||||
end
|
||||
rescue => original_exception
|
||||
translated_exception = translate_exception_class(original_exception, nil, nil)
|
||||
retry_deadline_exceeded = deadline && deadline < Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
|
||||
if !retry_deadline_exceeded && retries_available > 0
|
||||
retries_available -= 1
|
||||
|
||||
if retryable_connection_error?(translated_exception)
|
||||
backoff(connection_retries - retries_available)
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
@verified = false
|
||||
|
||||
raise translated_exception
|
||||
end
|
||||
end
|
||||
|
||||
# Reset the state of this connection, directing the DBMS to clear
|
||||
# transactions and other connection-related server-side state. Usually a
|
||||
# database-dependent operation.
|
||||
#
|
||||
# If a database driver or protocol does not support such a feature,
|
||||
# implementors may alias this to #reconnect!. Otherwise, implementors
|
||||
# should call super immediately after resetting the connection (and while
|
||||
# still holding @lock).
|
||||
def reset!
|
||||
clear_cache!(new_connection: true)
|
||||
reset_transaction
|
||||
attempt_configure_connection
|
||||
end
|
||||
|
||||
# Checks whether the connection to the database is still active (i.e. not stale).
|
||||
# This is done under the hood by calling #active?. If the connection
|
||||
# is no longer active, then this method will reconnect to the database.
|
||||
def verify!
|
||||
unless active?
|
||||
@lock.synchronize do
|
||||
if @unconfigured_connection
|
||||
@raw_connection = @unconfigured_connection
|
||||
@unconfigured_connection = nil
|
||||
attempt_configure_connection
|
||||
@verified = true
|
||||
return
|
||||
end
|
||||
|
||||
reconnect!(restore_transactions: true)
|
||||
end
|
||||
end
|
||||
|
||||
@verified = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Lint/RescueException
|
||||
# rubocop:enable Lint/AmbiguousOperatorPrecedence
|
||||
# rubocop:enable Naming/RescuedExceptionsVariableName
|
||||
# rubocop:enable Style/NumericPredicate
|
||||
# rubocop:enable Cop/AvoidReturnFromBlocks
|
||||
# rubocop:enable Style/RescueStandardError
|
@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
if defined?(Gitlab) && ActiveRecord.version.to_s != '7.1.5.1'
|
||||
raise "This patch is only needed in Rails 7.1.5.1 for https://github.com/rails/rails/issues/51780"
|
||||
end
|
||||
|
||||
# rubocop:disable Layout/EmptyLinesAroundAccessModifier -- This is copied directly from Rails.
|
||||
# rubocop:disable Layout/IndentationWidth -- This is copied directly from Rails.
|
||||
# rubocop:disable Layout/IndentationConsistency -- This is copied directly from Rails.
|
||||
# rubocop:disable Style/MissingRespondToMissing -- This is copied directly from Rails.
|
||||
# rubocop:disable Cop/LineBreakAroundConditionalBlock -- This is copied directly from Rails.
|
||||
# rubocop:disable Style/IfUnlessModifier -- This is copied directly from Rails.
|
||||
# rubocop:disable GitlabSecurity/PublicSend -- This is copied directly from Rails.
|
||||
module ActiveRecord
|
||||
module AttributeMethods
|
||||
private
|
||||
def method_missing(name, ...)
|
||||
unless self.class.attribute_methods_generated?
|
||||
if self.class.method_defined?(name)
|
||||
# The method is explicitly defined in the model, but calls a generated
|
||||
# method with super. So we must resume the call chain at the right setp.
|
||||
last_method = method(name)
|
||||
last_method = last_method.super_method while last_method.super_method
|
||||
self.class.define_attribute_methods
|
||||
if last_method.super_method
|
||||
return last_method.super_method.call(...)
|
||||
end
|
||||
elsif self.class.define_attribute_methods | self.class.generate_alias_attributes
|
||||
# Some attribute methods weren't generated yet, we retry the call
|
||||
return public_send(name, ...)
|
||||
end
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Layout/EmptyLinesAroundAccessModifier
|
||||
# rubocop:enable Layout/IndentationWidth
|
||||
# rubocop:enable Layout/IndentationConsistency
|
||||
# rubocop:enable Style/MissingRespondToMissing
|
||||
# rubocop:enable Cop/LineBreakAroundConditionalBlock
|
||||
# rubocop:enable Style/IfUnlessModifier
|
||||
# rubocop:enable GitlabSecurity/PublicSend
|
Reference in New Issue
Block a user