active_replicas 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +17 -1
- data/lib/active_replicas/rails4/process_local_connection_handler.rb +29 -9
- data/lib/active_replicas/version.rb +1 -1
- data/lib/active_replicas.rb +0 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5449461c40a999c9979801ce9395a9a7f3c43d3
|
4
|
+
data.tar.gz: 3a222a36c5715a2ae8709f7359d77ec3210114a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ce1364563eff9ec842ad01446747f45c0815cca827a251411158f3b7d67d481a930e6af8bedddc32219b561e311753c9406cfe3e5873a0cccc1afcfb5b55e57
|
7
|
+
data.tar.gz: 17314509e2bdfdc639bc9c608d03e050a5f291f1a2cead0057e4ebd05ff3bbf5d90809bbdd3def2d21581bd0be1526205c86b19fc47acaee6a5389b7d5bbce2c
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# ActiveReplicas
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/dirk/active_replicas)
|
4
|
+
|
5
|
+
Drop-in read-replica querying in ActiveRecord. It proxies around ActiveRecord's connection to send read-only queries to replica databases; writes will automatically go to the primary and "stick" the request into using the primary for any further queries.
|
4
6
|
|
5
7
|
This is heavily inspired by [Kickstarter's `replica_pools`](https://github.com/kickstarter/replica_pools) gem. It seeks to improve on that gem by better interfacing with ActiveRecord's connection pools.
|
6
8
|
|
@@ -24,6 +26,20 @@ ActiveReplicas::Railtie.hijack_active_record primary: { url: 'mysql2://user@prim
|
|
24
26
|
|
25
27
|
**Note**: ActiveReplicas does not do anything automatically. It only injects itself into ActiveRecord when you tell it do so (see above).
|
26
28
|
|
29
|
+
## How it works
|
30
|
+
|
31
|
+
A few things happen when you call [`hijack_active_record`](http://www.rubydoc.info/github/dirk/active_replicas/master/ActiveReplicas/Railtie#hijack_active_record-class_method):
|
32
|
+
|
33
|
+
- It defines delegations for the [connection](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html) methods that can be sent to replicas and the methods that must be sent to a primary.
|
34
|
+
- It sets up a [`ConnectionHandler`](http://www.rubydoc.info/github/dirk/active_replicas/master/ActiveReplicas/Rails4/ConnectionHandler) that will act in place of ActiveRecord's normal connection handler.
|
35
|
+
- It replaces ActiveRecord's log subscriber with its own [`LogSubscriber`](http://www.rubydoc.info/github/dirk/active_replicas/master/ActiveReplicas/LogSubscriber) which adds information about replica/primary status to logging messages.
|
36
|
+
|
37
|
+
The new connection handler manages connection pools for each configured primary and replica database(s). Externally it provides instances of [`ProxyingConnectionPool`](http://www.rubydoc.info/github/dirk/active_replicas/master/ActiveReplicas/ProxyingConnectionPool) in place of normal connection pools. Those proxying pools then forward connection methods to primary or replica pools.
|
38
|
+
|
39
|
+
### Using it with Ruby on Rails
|
40
|
+
|
41
|
+
ActiveReplicas works seamlessly within the Rails request lifecycle. It extends the [`clear_active_connections!` called in ActiveRecord's middleware](https://github.com/rails/rails/blob/4-2-stable/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L645-L663) to not only clear the active connections (releasing them back to their respective pool) but also resets the primary/replica state. That way the next connection will start out using a replica.
|
42
|
+
|
27
43
|
## Contributing
|
28
44
|
|
29
45
|
Bug reports and pull requests are welcome on [GitHub][]. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
@@ -13,12 +13,7 @@ module ActiveReplicas
|
|
13
13
|
|
14
14
|
def initialize(proxy_configuration)
|
15
15
|
@proxy_configuration = proxy_configuration
|
16
|
-
|
17
|
-
@primary_pool = Helpers.connection_pool_for_spec @proxy_configuration[:primary]
|
18
|
-
|
19
|
-
@replica_pools = (@proxy_configuration[:replicas] || {}).map do |name, config_spec|
|
20
|
-
[name, Helpers.connection_pool_for_spec(config_spec)]
|
21
|
-
end.to_h
|
16
|
+
initialize_pools
|
22
17
|
|
23
18
|
# Each thread gets its own `ProxyingConnectionPool`.
|
24
19
|
@reserved_proxies = Concurrent::Map.new
|
@@ -33,10 +28,23 @@ module ActiveReplicas
|
|
33
28
|
|
34
29
|
def establish_connection(owner, spec)
|
35
30
|
prefix = '[ActiveReplicas::Rails4::ConnectionHandler#establish_connection]'
|
36
|
-
|
37
|
-
ActiveRecord::Base.logger&.info "#{prefix} Called from:\n" + Kernel.caller.first(5).map {|t| " #{t}" }.join("\n")
|
31
|
+
details = "#{spec.config.inspect} (owner: #{owner.inspect})"
|
38
32
|
|
39
|
-
|
33
|
+
synchronize do
|
34
|
+
if @proxy_configuration[:primary] == spec.config
|
35
|
+
ActiveRecord::Base.logger&.warn "#{prefix} Ignoring new spec as it matches existing primary spec: #{details}"
|
36
|
+
else
|
37
|
+
ActiveRecord::Base.logger&.warn "#{prefix} Overwriting connection spec: #{details}"
|
38
|
+
ActiveRecord::Base.logger&.info "#{prefix} Called from:\n" + Kernel.caller.map {|t| " #{t}" }.join("\n")
|
39
|
+
@proxy_configuration = { primary: spec.config }
|
40
|
+
end
|
41
|
+
|
42
|
+
clear_all_connections!
|
43
|
+
initialize_pools
|
44
|
+
|
45
|
+
# Rails returns a connection pool.
|
46
|
+
retrieve_connection_pool owner
|
47
|
+
end
|
40
48
|
end
|
41
49
|
|
42
50
|
def active_connections?
|
@@ -114,6 +122,18 @@ module ActiveReplicas
|
|
114
122
|
def current_thread_id
|
115
123
|
Thread.current.object_id
|
116
124
|
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
# Sets up `@primary_pool` and `@replica_pools` from the current
|
129
|
+
# `@proxy_configuration`.
|
130
|
+
def initialize_pools
|
131
|
+
@primary_pool = Helpers.connection_pool_for_spec @proxy_configuration[:primary]
|
132
|
+
|
133
|
+
@replica_pools = (@proxy_configuration[:replicas] || {}).map do |name, config_spec|
|
134
|
+
[name, Helpers.connection_pool_for_spec(config_spec)]
|
135
|
+
end.to_h
|
136
|
+
end
|
117
137
|
end
|
118
138
|
end
|
119
139
|
end
|
data/lib/active_replicas.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_replicas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dirk Gadsden
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|