Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot
2025-05-20 06:07:37 +00:00
parent d89b4de31a
commit 90f2c67875
42 changed files with 347 additions and 165 deletions

View File

@ -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"

View File

@ -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

View File

@ -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