active_replicas 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/dirk/active_replicas.svg?branch=master)](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
|