Module: ResilientReads::AdapterPatch

Defined in:
lib/resilient_reads/adapter_patch.rb

Overview

Prepended onto the database adapter (e.g. PostgreSQLAdapter, Mysql2Adapter, TrilogyAdapter). Intercepts raw_execute and routes SELECT queries to a healthy replica when inside a distribute_reads block. Writes always pass through to the primary connection.

Uses *args/**kwargs to stay compatible across Rails versions:

Rails 7.1/7.2: raw_execute(sql, name, async:, allow_retry:, materialize_transactions:)
Rails 8.0+:    raw_execute(sql, name, binds, prepare:, async:, allow_retry:, materialize_transactions:, batch:)

Constant Summary collapse

SKIP_NAMES =

Query names that should never be routed to a replica. These are schema introspection or internal bookkeeping queries that run during model loading and connection setup.

Set.new(%w[SCHEMA EXPLAIN]).freeze

Instance Method Summary collapse

Instance Method Details

#raw_execute(sql, *args, **kwargs) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/resilient_reads/adapter_patch.rb', line 16

def raw_execute(sql, *args, **kwargs)
  ctx = Thread.current[:resilient_reads_context]
  name = args.first

  if ctx &&
     ctx[:distributing] &&
     !ctx[:on_replica] &&
     !ctx[:routing] &&
     !skip_replica_routing?(sql, name) &&
     open_transactions.zero?

    execute_on_replica(sql, ctx, *args, **kwargs)
  else
    if ctx && ctx[:distributing] && write_query?(sql)
      ResilientReads.log_query("primary", sql, name, reason: "write query")
    end
    super(sql, *args, **kwargs)
  end
end