Skip to content

Fix handling for `GitlabSchemasValidateConnection` for early start

What does this MR do and why?

It appears that each connection needs to be adopted. However, in it's initial phase (before being adopted) the Rails might execute SQL queries to configure the connection settings (collation, timeouts, etc.). This will happen before the connection is actually assigned to the connection pool, as if such connection will be failed to be initialized it will be orphaned.

Only after the connection is adopted we truly know to whom it belongs as db_config or connection_klass. Before we return unknown and fail fetching schemas. It is fine to return empty list of schemas in this particular case as we will ignore such invocations.

This do happen since we insert a number of subscribers to observe SQL queries:

  • marginalia
  • query-details
  • transaction observers
  • measuring

However, this makes those observes to be fired for those initialization time queries, before the connection was adopted.

Fixes:

Execution stack

module ActiveRecord
  module ConnectionAdapters
    class ConnectionPool
      def new_connection
        Base.public_send(db_config.adapter_method, db_config.configuration_hash).tap do |conn|
          conn.check_version
        end
      end
    end

    class PostgreSQLAdapter
      include PostgreSQL::SchemaStatements

      # Connects to a PostgreSQL server and sets up the adapter depending on the
      # connected server's characteristics.
      def connect
        @connection = self.class.new_client(@connection_parameters)
        configure_connection
        ...
      end

      # Configures the encoding, verbosity, schema search path, and time zone of the connection.
      # This is called by #connect and should not be called manually.
      def configure_connection
        ...
        self.client_min_messages = @config[:min_messages] || "warning"
        ...
      end
    end
  end

  module PostgreSQL
    module SchemaStatements
      # Set the client message level.
      def client_min_messages=(level)
        execute("SET client_min_messages TO '#{level}'", "SCHEMA")
      end
    end
  end
end

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Kamil Trzciński (Back 2025-01-01)

Merge request reports

Loading