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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e56f8bd047e2f96b83a8246b4cdbcd428dd4e095
4
- data.tar.gz: e02a7e2680c7bc60aa47c2cd75a25ca704f3a5c5
3
+ metadata.gz: e5449461c40a999c9979801ce9395a9a7f3c43d3
4
+ data.tar.gz: 3a222a36c5715a2ae8709f7359d77ec3210114a3
5
5
  SHA512:
6
- metadata.gz: f430544ad26fd4f894addafb5961ea1cfc5aabf99fc565a206556bf70d302efe7afc4b4ae4447345c95c4ec1793d95d109400aa1995b7e72bfe4c1c644d2276e
7
- data.tar.gz: 755fc9c0a43f3860d4c8f2f5b7ef984740f401a51b10dc50c29f0da1bf964648df7d813457272529ab9da73177ce4e2a94db7e64b9e03d622fa305b0e8c57f66
6
+ metadata.gz: 3ce1364563eff9ec842ad01446747f45c0815cca827a251411158f3b7d67d481a930e6af8bedddc32219b561e311753c9406cfe3e5873a0cccc1afcfb5b55e57
7
+ data.tar.gz: 17314509e2bdfdc639bc9c608d03e050a5f291f1a2cead0057e4ebd05ff3bbf5d90809bbdd3def2d21581bd0be1526205c86b19fc47acaee6a5389b7d5bbce2c
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # ActiveReplicas
2
2
 
3
- Allows you to automatically 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.
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
- ActiveRecord::Base.logger&.warn "#{prefix} Ignoring spec for #{owner.inspect}: #{spec.inspect}"
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
- current_proxy
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
@@ -1,3 +1,3 @@
1
1
  module ActiveReplicas
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -7,7 +7,6 @@ if defined? ActiveRecord
7
7
  version = ActiveRecord::VERSION::MAJOR
8
8
 
9
9
  if version == 4
10
- require 'active_replicas/rails4/helpers'
11
10
  require 'active_replicas/rails4/connection_handler'
12
11
  else
13
12
  raise "Unsupported ActiveRecord version: #{version}"
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.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-04 00:00:00.000000000 Z
11
+ date: 2016-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby