instance method with_raw_connection

Ruby on Rails 8.1.2

Since v7.1.6 Private — implementation detail, not part of the public API

Available in: v7.1.6 v7.2.3 v8.0.4 v8.1.2

Signature

with_raw_connection(allow_retry: false, materialize_transactions: true)

Lock the monitor, ensure we’re properly connected and transactions are materialized, and then yield the underlying raw connection object.

If allow_retry is true, a connection-related exception will cause an automatic reconnect and re-run of the block, up to the connection’s configured connection_retries setting and the configured retry_deadline limit. (Note that when allow_retry is true, it’s possible to return without having marked the connection as verified. If the block is guaranteed to exercise the connection, consider calling verified! to avoid needless verification queries in subsequent calls.)

If materialize_transactions is false, the block will be run without ensuring virtual transactions have been materialized in the DB server’s state. The active transaction will also remain clean (if it is not already dirty), meaning it’s able to be restored by reconnecting and opening an equivalent-depth set of new transactions. This should only be used by transaction control methods, and internal transaction-agnostic queries.

It’s not the primary use case, so not something to optimize for, but note that this method does need to be re-entrant: materialize_transactions will re-enter if it has work to do, and the yield block can also do so under some circumstances.

In the latter case, we really ought to guarantee the inner call will not reconnect (which would interfere with the still-yielded connection in the outer block), but we currently provide no special enforcement there.

Parameters

allow_retry key = false
materialize_transactions key = true
Source
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 1054
        def with_raw_connection(allow_retry: false, materialize_transactions: true)
          @lock.synchronize do
            connect! if @raw_connection.nil? && reconnect_can_restore_state?

            self.materialize_transactions if materialize_transactions

            retries_available = allow_retry ? connection_retries : 0
            deadline = retry_deadline && Process.clock_gettime(Process::CLOCK_MONOTONIC) + retry_deadline
            reconnectable = reconnect_can_restore_state?

            if @verified
              # Cool, we're confident the connection's ready to use. (Note this might have
              # become true during the above #materialize_transactions.)
            elsif (last_activity = seconds_since_last_activity) && last_activity < verify_timeout
              # We haven't actually verified the connection since we acquired it, but it
              # has been used very recently. We're going to assume it's still okay.
            elsif reconnectable
              if allow_retry
                # Not sure about the connection yet, but if anything goes wrong we can
                # just reconnect and re-run our query
              else
                # We can reconnect if needed, but we don't trust the upcoming query to be
                # safely re-runnable: let's verify the connection to be sure
                verify!
              end
            else
              # We don't know whether the connection is okay, but it also doesn't matter:
              # we wouldn't be able to reconnect anyway. We're just going to run our query
              # and hope for the best.
            end

            begin
              yield @raw_connection
            rescue => original_exception
              translated_exception = translate_exception_class(original_exception, nil, nil)
              invalidate_transaction(translated_exception)
              retry_deadline_exceeded = deadline && deadline < Process.clock_gettime(Process::CLOCK_MONOTONIC)

              if !retry_deadline_exceeded && retries_available > 0
                retries_available -= 1

                if retryable_query_error?(translated_exception)
                  backoff(connection_retries - retries_available)
                  retry
                elsif reconnectable && retryable_connection_error?(translated_exception)
                  reconnect!(restore_transactions: true)
                  # Only allowed to reconnect once, because reconnect! has its own retry
                  # loop
                  reconnectable = false
                  retry
                end
              end

              unless retryable_query_error?(translated_exception)
                # Barring a known-retryable error inside the query (regardless of
                # whether we were in a _position_ to retry it), we should infer that
                # there's likely a real problem with the connection.
                @last_activity = nil
                @verified = false
              end

              raise translated_exception
            ensure
              dirty_current_transaction if materialize_transactions
            end
          end
        end

Defined in activerecord/lib/active_record/connection_adapters/abstract_adapter.rb line 1054 · View on GitHub · Improve this page · Find usages on GitHub

Defined in ActiveRecord::ConnectionAdapters::AbstractAdapter

Type at least 2 characters to search.

Use the arrow keys to navigate results, Enter to open one, Escape to close.

Keyboard shortcuts

/
Focus search
⌘K / Ctrl-K
Command palette
?
This help
Esc
Close