active_record_proxy_adapters 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b80e3ab832bc332967c0f4840f9f35563725497e61a48339c46e4f65a15b2458
4
- data.tar.gz: fc85aed94e09aa25bd15e46102ae318f9b790bc2bb67a24243c2340952ff4fa2
3
+ metadata.gz: 5312effcf68a3305eb5e7804440112433f5b6837d6b71e7d122145eac4741619
4
+ data.tar.gz: 50586657daa02e76dfffebbe1faf8df5093198471faf847cec97cd16634c0c17
5
5
  SHA512:
6
- metadata.gz: 5a81cf2441d0f1548311474fbaa3326b9d2fbccc0b25c481408f0f99ce6634710dc589e0aed60f63ca55e5debe2635eb4cd6a75c2a0cf444fb7929292dc02dac
7
- data.tar.gz: c4bd34a35fa68b8257a5839b99055efdd11d18ce436afea98fd695475c4dae7cfda7ecc26fc2aed61f0981258c65684f22185c6d8fddc143ceb06b400b9219b1
6
+ metadata.gz: 707b80a3618328639126d13f3f76bb8123105019b3e30c75f15c66a66a88d49aa5de4301fe70b25ff5356ef37e54ebff896f4cab0160cadbb79d08ae9cf0dc4e
7
+ data.tar.gz: 6b84984e33cf87abe9a12f5553bccffc32e2a9563a0c859c488cdae4be4c3a019ffce01242648620c67bb85a16dc61d982f0be8ecba83943f01c718e067743dc
data/CHANGELOG.md CHANGED
@@ -1,37 +1,26 @@
1
1
  ## [Unreleased]
2
2
 
3
- - Handle PendingMigrationConnection introduced by Rails 7.2 and backported to Rails 7.1
4
- - Stick to same connection throughout request span
5
-
6
- ## [0.2.1] - 2025-01-02
7
-
8
- - Fix replica connection pool getter when specific connection name is not found https://github.com/Nasdaq/active_record_proxy_adapters/commit/847e150dd21c5bc619745ee1d9d8fcaa9b8f2eea
9
-
10
3
  ## [0.2.0] - 2024-12-24
11
4
 
12
- - Add custom log subscriber to tag queries based on the adapter being used https://github.com/Nasdaq/active_record_proxy_adapters/commit/68b8c1f4191388eb957bf12e0f84289da667e940
13
-
14
- ## [0.1.4] - 2025-01-02
15
-
16
- - Fix replica connection pool getter when specific connection name is not found https://github.com/Nasdaq/active_record_proxy_adapters/commit/88b32a282b54d420e652f638656dbcf063ac8796
5
+ - Add custom log subscriber to tag queries based on the adapter being used (68b8c1f4191388eb957bf12e0f84289da667e940)
17
6
 
18
7
  ## [0.1.3] - 2024-12-24
19
8
 
20
- - Fix replica connection pool getter when database configurations have multiple replicas https://github.com/Nasdaq/active_record_proxy_adapters/commit/ea5a33997da45ac073f166b3fbd2d12426053cd6
21
- - Retrieve replica pool without checking out a connection https://github.com/Nasdaq/active_record_proxy_adapters/commit/6470ef58e851082ae1f7a860ecdb5b451ef903c8
9
+ - Fix replica connection pool getter when database configurations have multiple replicas (ea5a33997da45ac073f166b3fbd2d12426053cd6)
10
+ - Retrieve replica pool without checking out a connection (6470ef58e851082ae1f7a860ecdb5b451ef903c8)
22
11
 
23
12
  ## [0.1.2] - 2024-12-16
24
13
 
25
- - Fix CTE regex matcher https://github.com/Nasdaq/active_record_proxy_adapters/commit/4b1d10bfd952fb1f5b102de8cc1a5bd05d25f5e9
14
+ - Fix CTE regex matcher (4b1d10bfd952fb1f5b102de8cc1a5bd05d25f5e9)
26
15
 
27
16
  ## [0.1.1] - 2024-11-27
28
17
 
29
- - Enable RubyGems MFA https://github.com/Nasdaq/active_record_proxy_adapters/commit/2a71b1f4354fb966cc0aa68231ca5837814e07ee
18
+ - Enable RubyGems MFA (2a71b1f4354fb966cc0aa68231ca5837814e07ee)
30
19
 
31
20
  ## [0.1.0] - 2024-11-19
32
21
 
33
- - Add PostgreSQLProxyAdapter https://github.com/Nasdaq/active_record_proxy_adapters/commit/2b3bb9f7359139519b32af3018ceb07fed8c6b33
22
+ - Add PostgreSQLProxyAdapter (2b3bb9f7359139519b32af3018ceb07fed8c6b33)
34
23
 
35
24
  ## [0.1.0.rc2] - 2024-10-28
36
25
 
37
- - Add PostgreSQLProxyAdapter https://github.com/Nasdaq/active_record_proxy_adapters/commit/2b3bb9f7359139519b32af3018ceb07fed8c6b33
26
+ - Add PostgreSQLProxyAdapter (2b3bb9f7359139519b32af3018ceb07fed8c6b33)
data/Dockerfile CHANGED
@@ -8,7 +8,7 @@ RUN apk --update add \
8
8
  build-base \
9
9
  git \
10
10
  postgresql-dev \
11
- postgresql17-client
11
+ postgresql-client
12
12
  RUN gem install bundler -v 2.5.13
13
13
 
14
14
  COPY . /app
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # ActiveRecordProxyAdapters
2
2
 
3
- [![Run Test Suite](https://github.com/Nasdaq/active_record_proxy_adapters/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/Nasdaq/active_record_proxy_adapters/actions/workflows/test.yml)
4
-
5
3
  A set of ActiveRecord adapters that leverage Rails native multiple database setup to allow automatic connection switching from _one_ primary pool to _one_ replica pool at the database statement level.
6
4
 
7
5
  ## Installation
@@ -1,7 +1,6 @@
1
1
  SET statement_timeout = 0;
2
2
  SET lock_timeout = 0;
3
3
  SET idle_in_transaction_session_timeout = 0;
4
- SET transaction_timeout = 0;
5
4
  SET client_encoding = 'UTF8';
6
5
  SET standard_conforming_strings = on;
7
6
  SELECT pg_catalog.set_config('search_path', '', false);
@@ -10,18 +9,16 @@ SET xmloption = content;
10
9
  SET client_min_messages = warning;
11
10
  SET row_security = off;
12
11
 
13
- SET default_tablespace = '';
14
-
15
- SET default_table_access_method = heap;
16
-
17
12
  --
18
- -- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -
13
+ -- Name: public; Type: SCHEMA; Schema: -; Owner: -
19
14
  --
20
15
 
21
- CREATE TABLE public.schema_migrations (
22
- version character varying(255) NOT NULL
23
- );
16
+ -- *not* creating schema, since initdb creates it
17
+
18
+
19
+ SET default_tablespace = '';
24
20
 
21
+ SET default_table_access_method = heap;
25
22
 
26
23
  --
27
24
  -- Name: users; Type: TABLE; Schema: public; Owner: -
@@ -71,13 +68,6 @@ ALTER TABLE ONLY public.users
71
68
  ADD CONSTRAINT users_pkey PRIMARY KEY (id);
72
69
 
73
70
 
74
- --
75
- -- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -
76
- --
77
-
78
- CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version);
79
-
80
-
81
71
  --
82
72
  -- PostgreSQL database dump complete
83
73
  --
data/docker-compose.yml CHANGED
@@ -50,6 +50,7 @@ services:
50
50
  - POSTGRES_LOG_STATEMENT=${POSTGRES_LOG_STATEMENT:-}
51
51
  - REPLICA_USER=replicator
52
52
  - REPLICA_PASSWORD=replicator
53
+ container_name: postgres_primary
53
54
  environment:
54
55
  POSTGRES_DB: postgres
55
56
  POSTGRES_USER: postgres_primary_test
@@ -5,8 +5,10 @@ require "active_support/core_ext/integer/time"
5
5
  module ActiveRecordProxyAdapters
6
6
  # Provides a global configuration object to configure how the proxy should behave.
7
7
  class Configuration
8
- PROXY_DELAY = 2.seconds.freeze
9
- CHECKOUT_TIMEOUT = 2.seconds.freeze
8
+ PROXY_DELAY = 2.seconds.freeze
9
+ CHECKOUT_TIMEOUT = 2.seconds.freeze
10
+ LOG_SUBSCRIBER_PRIMARY_PREFIX = proc { |event| "#{event.payload[:connection].class::ADAPTER_NAME} Primary" }.freeze
11
+ LOG_SUBSCRIBER_REPLICA_PREFIX = proc { |event| "#{event.payload[:connection].class::ADAPTER_NAME} Replica" }.freeze
10
12
 
11
13
  # @return [ActiveSupport::Duration] How long the proxy should reroute all read requests to the primary database
12
14
  # since the latest write. Defaults to PROXY_DELAY.
@@ -15,9 +17,25 @@ module ActiveRecordProxyAdapters
15
17
  # Defaults to CHECKOUT_TIMEOUT.
16
18
  attr_accessor :checkout_timeout
17
19
 
20
+ # @return [Proc] Prefix for the log subscriber when the primary database is used.
21
+ attr_reader :log_subscriber_primary_prefix
22
+
23
+ # @return [Proc] Prefix for the log subscriber when the replica database is used.
24
+ attr_reader :log_subscriber_replica_prefix
25
+
18
26
  def initialize
19
- self.proxy_delay = PROXY_DELAY
20
- self.checkout_timeout = CHECKOUT_TIMEOUT
27
+ self.proxy_delay = PROXY_DELAY
28
+ self.checkout_timeout = CHECKOUT_TIMEOUT
29
+ self.log_subscriber_primary_prefix = LOG_SUBSCRIBER_PRIMARY_PREFIX
30
+ self.log_subscriber_replica_prefix = LOG_SUBSCRIBER_REPLICA_PREFIX
31
+ end
32
+
33
+ def log_subscriber_primary_prefix=(prefix)
34
+ @log_subscriber_primary_prefix = prefix.is_a?(Proc) ? prefix : proc { prefix.to_s }
35
+ end
36
+
37
+ def log_subscriber_replica_prefix=(prefix)
38
+ @log_subscriber_replica_prefix = prefix.is_a?(Proc) ? prefix : proc { prefix.to_s }
21
39
  end
22
40
  end
23
41
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecordProxyAdapters
4
+ class LogSubscriber < ActiveRecord::LogSubscriber # rubocop:disable Style/Documentation
5
+ attach_to :active_record
6
+
7
+ IGNORE_PAYLOAD_NAMES = %w[SCHEMA EXPLAIN].freeze
8
+
9
+ def sql(event)
10
+ payload = event.payload
11
+ name = payload[:name]
12
+ unless IGNORE_PAYLOAD_NAMES.include?(name)
13
+ name = [database_instance_prefix_for(event), name].compact.join(" ")
14
+ payload[:name] = name
15
+ end
16
+ super
17
+ end
18
+
19
+ protected
20
+
21
+ def database_instance_prefix_for(event)
22
+ connection = event.payload[:connection]
23
+ config = connection.instance_variable_get(:@config)
24
+ prefix = if config[:replica] || config["replica"]
25
+ log_subscriber_replica_prefix
26
+ else
27
+ log_subscriber_primary_prefix
28
+ end
29
+
30
+ "[#{prefix.call(event)}]"
31
+ end
32
+
33
+ private
34
+
35
+ delegate :log_subscriber_primary_prefix, :log_subscriber_replica_prefix, to: :config
36
+
37
+ def config
38
+ ActiveRecordProxyAdapters.config
39
+ end
40
+ end
41
+ end
@@ -62,7 +62,7 @@ module ActiveRecordProxyAdapters
62
62
 
63
63
  attr_reader :primary_connection, :last_write_at, :active_record_context
64
64
 
65
- delegate :connection_handler, to: :connection_class
65
+ delegate :connection_handler, :connected_to_stack, to: :connection_class
66
66
  delegate :reading_role, :writing_role, to: :active_record_context
67
67
 
68
68
  def replica_pool_unavailable?
@@ -70,18 +70,9 @@ module ActiveRecordProxyAdapters
70
70
  end
71
71
 
72
72
  def replica_pool
73
- # use default handler if the connection pool for specific class is not found
74
- specific_replica_pool || default_replica_pool
75
- end
76
-
77
- def specific_replica_pool
78
73
  connection_handler.retrieve_connection_pool(connection_class.name, role: reading_role)
79
74
  end
80
75
 
81
- def default_replica_pool
82
- connection_handler.retrieve_connection_pool(ActiveRecord::Base.name, role: reading_role)
83
- end
84
-
85
76
  def connection_class
86
77
  active_record_context.connection_class_for(primary_connection)
87
78
  end
@@ -120,25 +111,11 @@ module ActiveRecordProxyAdapters
120
111
  [reading_role, writing_role].include?(role) ? role : nil
121
112
  end
122
113
 
123
- def connected_to_stack
124
- return connection_class.connected_to_stack if connection_class.respond_to?(:connected_to_stack)
125
-
126
- # handle Rails 7.2+ pending migrations Connection
127
- return [{ role: writing_role }] if pending_migration_connection?
128
-
129
- []
130
- end
131
-
132
- def pending_migration_connection?
133
- active_record_context.active_record_v7_1_or_greater? &&
134
- connection_class.name == "ActiveRecord::PendingMigrationConnection"
135
- end
136
-
137
114
  def connection_for(role, sql_string)
138
115
  connection = primary_connection if role == writing_role || replica_pool_unavailable?
139
116
  connection ||= checkout_replica_connection
140
117
 
141
- result = connected_to(role:) { yield connection }
118
+ result = yield(connection)
142
119
 
143
120
  update_primary_latest_write_timestamp if !replica_connection?(connection) && write_statement?(sql_string)
144
121
 
@@ -147,12 +124,6 @@ module ActiveRecordProxyAdapters
147
124
  replica_connection?(connection) && replica_pool.checkin(connection)
148
125
  end
149
126
 
150
- def connected_to(role:, &block)
151
- return block.call unless connection_class.respond_to?(:connected_to)
152
-
153
- connection_class.connected_to(role:, &block)
154
- end
155
-
156
127
  def replica_connection?(connection)
157
128
  connection && connection != primary_connection
158
129
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordProxyAdapters
4
- VERSION = "0.1.5"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -1,4 +1,4 @@
1
- FROM docker.io/postgres:17-alpine
1
+ FROM docker.io/postgres:14-alpine
2
2
 
3
3
  ARG REPLICA_USER=replicator
4
4
  ARG REPLICA_PASSWORD=replicator
@@ -1,4 +1,4 @@
1
- FROM docker.io/postgres:17-alpine
1
+ FROM docker.io/postgres:14-alpine
2
2
 
3
3
  ENV PRIMARY_DATABASE_HOST=localhost
4
4
  ENV PRIMARY_DATABASE_PORT=5432
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_proxy_adapters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Cruz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-04 00:00:00.000000000 Z
11
+ date: 2024-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -77,6 +77,7 @@ files:
77
77
  - lib/active_record_proxy_adapters/configuration.rb
78
78
  - lib/active_record_proxy_adapters/connection_handling.rb
79
79
  - lib/active_record_proxy_adapters/hijackable.rb
80
+ - lib/active_record_proxy_adapters/log_subscriber.rb
80
81
  - lib/active_record_proxy_adapters/postgresql_proxy.rb
81
82
  - lib/active_record_proxy_adapters/primary_replica_proxy.rb
82
83
  - lib/active_record_proxy_adapters/railtie.rb