slave_pools 0.1.2 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,67 +2,29 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe SlavePools do
4
4
 
5
- before(:all) do
6
- ActiveRecord::Base.configurations = SLAVE_POOLS_SPEC_CONFIG
7
- ActiveRecord::Base.establish_connection :test
8
- @sql = 'SELECT NOW()'
5
+ before(:each) do
6
+ SlavePools.pools.each{|_, pool| pool.reset }
7
+ @proxy = SlavePools.proxy
9
8
  end
10
-
11
- context "with no setup" do
12
- it "should not error out if next slave is called and SlavePools is not set up" do
13
- SlavePools.should_receive(:active?).and_return(false)
14
- SlavePools.next_slave!.should be_nil
15
- end
16
-
17
- it "should not error out if current is called and SlavePools is not set up" do
18
- SlavePools.should_receive(:active?).and_return(false)
19
- SlavePools.current.should be_nil
20
- end
21
-
22
- it "should yield on a with_pool call if slave_pools is not active" do
23
- SlavePools.should_receive(:active?).and_return(false)
24
- ActiveRecord::Base.connection.should_receive(:execute)
25
- SlavePools.with_pool('admin') {ActiveRecord::Base.connection.execute(@sql)}
26
- end
27
9
 
28
- it "should yield on a with_master call if slave_pools is not active" do
29
- SlavePools.should_receive(:active?).and_return(false)
30
- ActiveRecord::Base.connection.should_receive(:execute)
31
- SlavePools.with_master {ActiveRecord::Base.connection.execute(@sql)}
32
- end
10
+ it 'should delegate next_slave! call to connection proxy' do
11
+ @proxy.should_receive(:next_slave!).exactly(1)
12
+ SlavePools.next_slave!
33
13
  end
34
-
35
- describe "Slave Pool Wrapper calls" do
36
- before(:each) do
37
- SlavePools.setup!
38
- @proxy = ActiveRecord::Base.connection_proxy
39
- end
40
-
41
- it 'should send next_slave! call to connection proxy' do
42
- ActiveRecord::Base.should_receive(:respond_to?).exactly(1)
43
- SlavePools.active?
44
- end
45
-
46
- it 'should send next_slave! call to connection proxy' do
47
- @proxy.should_receive(:next_slave!).exactly(1)
48
- SlavePools.next_slave!
49
- end
50
-
51
- it 'should send with_pool call to connection proxy' do
52
- @proxy.should_receive(:with_pool).exactly(1)
53
- SlavePools.with_pool('test')
54
- end
55
-
56
- it 'should send with_master call to connection proxy' do
57
- @proxy.should_receive(:with_master).exactly(1)
58
- SlavePools.with_master
59
- end
60
14
 
61
- it 'should send current call to connection proxy' do
62
- @proxy.should_receive(:current).exactly(1)
63
- SlavePools.current
64
- end
15
+ it 'should delegate with_pool call to connection proxy' do
16
+ @proxy.should_receive(:with_pool).exactly(1)
17
+ SlavePools.with_pool('test')
18
+ end
19
+
20
+ it 'should delegate with_master call to connection proxy' do
21
+ @proxy.should_receive(:with_master).exactly(1)
22
+ SlavePools.with_master
23
+ end
65
24
 
25
+ it 'should delegate current call to connection proxy' do
26
+ @proxy.should_receive(:current).exactly(1)
27
+ SlavePools.current
66
28
  end
67
29
 
68
30
  end
data/spec/spec_helper.rb CHANGED
@@ -2,16 +2,44 @@ require 'rubygems'
2
2
  require 'bundler/setup'
3
3
  require 'logger'
4
4
 
5
- require 'slave_pools'
6
-
7
5
  module Rails
8
6
  def self.env
9
7
  ActiveSupport::StringInquirer.new("test")
10
8
  end
11
9
  end
12
10
 
13
- SLAVE_POOLS_SPEC_DIR = File.dirname(__FILE__)
14
- SLAVE_POOLS_SPEC_CONFIG = YAML::load(File.open(SLAVE_POOLS_SPEC_DIR + '/config/database.yml'))
11
+ require 'active_record'
12
+ spec_dir = File.dirname(__FILE__)
13
+ ActiveRecord::Base.logger = Logger.new(spec_dir + "/debug.log")
14
+ ActiveRecord::Base.configurations = YAML::load(File.open(spec_dir + '/config/database.yml'))
15
+
16
+ ActiveRecord::Base.establish_connection :test
17
+ ActiveRecord::Migration.verbose = false
18
+ ActiveRecord::Migration.create_table(:test_models, :force => true) {}
19
+ ActiveRecord::Migration.create_table(:test_subs, :force => true) {|t| t.integer :test_model_id}
15
20
 
16
- ActiveRecord::Base.logger = Logger.new(SLAVE_POOLS_SPEC_DIR + "/debug.log")
17
- ActiveRecord::Base.configurations = SLAVE_POOLS_SPEC_CONFIG
21
+ require 'slave_pools'
22
+ SlavePools::Engine.initializers.each(&:run)
23
+ ActiveSupport.run_load_hooks(:after_initialize, SlavePools::Engine)
24
+
25
+ module SlavePools::Testing
26
+ # Creates aliases for the slave connections in each pool
27
+ # for easy reference in tests.
28
+ def create_slave_aliases(proxy)
29
+ proxy.slave_pools.each do |name, pool|
30
+ pool.slaves.each.with_index do |slave, i|
31
+ instance_variable_set("@#{name}_slave#{i + 1}", slave.retrieve_connection)
32
+ end
33
+ end
34
+ end
35
+
36
+ def reset_proxy(proxy)
37
+ proxy.slave_pools.each{|_, pool| pool.reset }
38
+ proxy.current_pool = proxy.slave_pools[:default]
39
+ proxy.current = proxy.current_slave
40
+ end
41
+ end
42
+
43
+ RSpec.configure do |c|
44
+ c.include SlavePools::Testing
45
+ end
metadata CHANGED
@@ -1,144 +1,141 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: slave_pools
3
- version: !ruby/object:Gem::Version
4
- hash: 31
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 2
10
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.rc1
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Dan Drabik
8
+ - Lance Ivy
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2013-07-11 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2013-12-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: activerecord
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
26
18
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 23
29
- segments:
30
- - 3
31
- - 2
32
- - 12
19
+ - !ruby/object:Gem::Version
33
20
  version: 3.2.12
34
21
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: mysql2
38
22
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 3.2.12
28
+ - !ruby/object:Gem::Dependency
29
+ name: mysql2
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
42
32
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 5
45
- segments:
46
- - 0
47
- - 3
48
- - 11
33
+ - !ruby/object:Gem::Version
49
34
  version: 0.3.11
50
35
  type: :development
51
- version_requirements: *id002
52
- - !ruby/object:Gem::Dependency
53
- name: rspec
54
36
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 3
61
- segments:
62
- - 0
63
- version: "0"
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 0.3.11
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
64
49
  type: :development
65
- version_requirements: *id003
66
- - !ruby/object:Gem::Dependency
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
67
57
  name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
68
64
  prerelease: false
69
- requirement: &id004 !ruby/object:Gem::Requirement
70
- none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- hash: 3
75
- segments:
76
- - 0
77
- version: "0"
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
78
77
  type: :development
79
- version_requirements: *id004
80
- description: Connection proxy for ActiveRecord for single master / multiple slave database groups
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description: Connection proxy for ActiveRecord for master / replica setups.
81
85
  email: dan@kickstarter.com
82
86
  executables: []
83
-
84
87
  extensions: []
85
-
86
- extra_rdoc_files:
87
- - LICENSE
88
- - README.rdoc
89
- files:
90
- - lib/slave_pools.rb
88
+ extra_rdoc_files: []
89
+ files:
91
90
  - lib/slave_pools/active_record_extensions.rb
91
+ - lib/slave_pools/config.rb
92
92
  - lib/slave_pools/connection_proxy.rb
93
+ - lib/slave_pools/engine.rb
94
+ - lib/slave_pools/hijack.rb
93
95
  - lib/slave_pools/observer_extensions.rb
94
- - lib/slave_pools/query_cache_compat.rb
95
- - lib/slave_pools/slave_pool.rb
96
+ - lib/slave_pools/pool.rb
97
+ - lib/slave_pools/pools.rb
98
+ - lib/slave_pools/query_cache.rb
99
+ - lib/slave_pools/version.rb
100
+ - lib/slave_pools.rb
96
101
  - LICENSE
97
- - README.rdoc
98
- - spec/config/database.yml
102
+ - README.md
103
+ - spec/config/test_model.rb
99
104
  - spec/connection_proxy_spec.rb
100
- - spec/slave_pool_spec.rb
105
+ - spec/observer_extensions_spec.rb
106
+ - spec/pool_spec.rb
107
+ - spec/query_cache_spec.rb
101
108
  - spec/slave_pools_spec.rb
102
109
  - spec/spec_helper.rb
103
- - slave_pools.gemspec
104
110
  homepage: https://github.com/kickstarter/slave_pools
105
- licenses:
111
+ licenses:
106
112
  - MIT
113
+ metadata: {}
107
114
  post_install_message:
108
- rdoc_options:
109
- - --line-numbers
110
- - --inline-source
111
- - --title
112
- - slave_pools
113
- - --main
114
- - README.rdoc
115
- require_paths:
115
+ rdoc_options: []
116
+ require_paths:
116
117
  - lib
117
- required_ruby_version: !ruby/object:Gem::Requirement
118
- none: false
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- hash: 3
123
- segments:
124
- - 0
125
- version: "0"
126
- required_rubygems_version: !ruby/object:Gem::Requirement
127
- none: false
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- hash: 11
132
- segments:
133
- - 1
134
- - 2
135
- version: "1.2"
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '1.2'
136
128
  requirements: []
137
-
138
129
  rubyforge_project:
139
- rubygems_version: 1.8.10
130
+ rubygems_version: 2.1.11
140
131
  signing_key:
141
- specification_version: 3
142
- summary: Connection proxy for ActiveRecord for single master / multiple slave database groups
143
- test_files: []
144
-
132
+ specification_version: 4
133
+ summary: Connection proxy for ActiveRecord for master / replica setups.
134
+ test_files:
135
+ - spec/config/test_model.rb
136
+ - spec/connection_proxy_spec.rb
137
+ - spec/observer_extensions_spec.rb
138
+ - spec/pool_spec.rb
139
+ - spec/query_cache_spec.rb
140
+ - spec/slave_pools_spec.rb
141
+ - spec/spec_helper.rb
data/README.rdoc DELETED
@@ -1,259 +0,0 @@
1
- = SlavePools
2
-
3
- == Easy Single Master/ Multiple Slave Setup for use in Ruby/Rails projects
4
-
5
- SlavePools builds a base layer of master/slave query splitting, by overwriting ActiveRecord's connection (with connection_proxy). With this in place, you can easily add a second layer of traffic splitting, by wrapping requests in the provided helper methods (examples below), and have a manageable master/slave solution for a standard rails application
6
-
7
- Overview
8
- * Sends only whitelisted SELECT-type queries to the Slaves
9
- * Sends all other queries to the Master
10
- * Works with query caching and transactions
11
- * Easy to separate types of read traffic into different collections of slaves (e.g. separating admin and user traffic)
12
- * Minimalist approach
13
- * doesn't include sharding
14
- * doesn't create a new ActiveRecord adapter
15
- * doesn't weight slave db's
16
- * Builds onto a standard database.yml file (gem doesn't initialize if no slaves are specified)
17
- * doesn't switch slaves on its own (the user specifies when to switch in their code)
18
-
19
- The SlavePools GEM started as a fork of Maximilian Sch\303\266fmann's https://github.com/schoefmax/multi_db
20
- The MultiDB gem was inspired by Rick Olson's "masochism"-Plugin
21
-
22
- == Usage
23
-
24
- Toggle to next slave:
25
- SlavePools.next_slave!
26
-
27
- Specify a different slave pool than the default:
28
- SlavePools.with_pool('other_pool') { #do stuff }
29
-
30
- Specifically use the master for a call:
31
- SlavePools.with_master { #do stuff }
32
-
33
- Determine if there are slaves:
34
- SlavePools.active?
35
-
36
- The gem, by default, sends writes and reads to the master and slave databases, respectfully. But in your app, if you write to the master during a request, you will probably want to read from the master in that request as well, in case there is replication. You will also probably want to read from the master on the next request (after a write to the master) to cover redirects.
37
-
38
- Using a standard rails application setup, you can achieve this by adding these example methods to your application controller (some of these may be folded in the gem, but leaving out for now):
39
-
40
- class ApplicationController < ActionController::Base
41
-
42
- around_filter :stick_to_master_for_updates
43
- around_filter :use_master_for_redirect #goes with above
44
- after_filter :switch_to_next_slave
45
-
46
- def switch_to_next_slave
47
- SlavePools.next_slave! if slaves?
48
- end
49
-
50
- def use_admin_slave_pool
51
- SlavePools.with_pool('admin') { yield } if slaves?
52
- end
53
-
54
- def stick_to_master_for_updates
55
- if slaves? && (request.post? || request.put? || request.delete?)
56
- SlavePools.with_master { yield }
57
- session[:stick_to_master] = 1
58
- else
59
- yield
60
- end
61
- end
62
-
63
- def use_master_for_redirect
64
- if slaves? && session[:stick_to_master]
65
- session[:stick_to_master] = nil
66
- SlavePools.with_master { yield }
67
- else
68
- yield
69
- end
70
- end
71
-
72
- def use_master
73
- if slaves?
74
- SlavePools.with_master { yield }
75
- session[:stick_to_master] = 1
76
- else
77
- yield
78
- end
79
- end
80
-
81
- def slaves?
82
- SlavePools.active?
83
- end
84
- end
85
-
86
- For other cases where you use the master for writes, you should wrap the request in a 'use_master' block
87
-
88
- class PostsController < ApplicationController
89
- around_filter :use_master, :only=>:index
90
-
91
- def index
92
- Activity.create()
93
- # index is a GET call, but we've decided to record something, so we want to wrap it in a use_master block
94
- end
95
- end
96
-
97
- * works with activerecord 3.2.12 (not tested with Rails 2)
98
-
99
- === Install
100
-
101
- Add to your Gemfile
102
-
103
- gem 'slave_pools'
104
-
105
- === Setup
106
-
107
- slave_pools identifies slave databases by looking for entries of the form
108
- "<tt><environment>_pool_<pool_name>_name_<db_name></tt>".
109
-
110
- In your database.yml, add sections for the slaves, e.g.:
111
-
112
- development: # that would be the master
113
- adapter: mysql
114
- database: myapp_production
115
- username: root
116
- password:
117
- host: localhost
118
-
119
- development_pool_default_name_slave1: # that would be a slave named 'slave1' in the 'default' pool
120
- adapter: mysql
121
- database: slave_db1
122
- username: root
123
- password:
124
- host: 10.0.0.2
125
-
126
- development_pool_default_name_slave2: # that would be a slave named 'slave2' in the 'default' pool
127
- ...
128
- development_pool_admin_name_slave1: # that would be a slave named 'slave1' in the 'admin' pool (db names can be reused across pools)
129
- ...
130
- development_pool_admin_name_another_slave: # that would be a slave named 'another_slave' in the 'admin' pool
131
-
132
- This also creates an abstract classes named <tt>SlavePools::DefaultDb1</tt> for each db of the form <tt>SlavePools::<PoolName><DbName></tt>etc. If no slaves are specified, the SlavePools setup does not run, and the development DB would be used as normal.
133
-
134
- For development testing, I recommend creating a read-only mysql user and just point all of your slave DB's to the your development DB using the read-only user.
135
-
136
- The Default SlavePool will be used for all requests, so you should name on of the pools 'default' (if there isn't a 'default' slave_pool, the first slave_pool specified becomes the default)
137
-
138
- To enable the proxy globally, add this to a config/initializers:
139
-
140
- SlavePools.setup!
141
-
142
- If you only want to enable it for specific environments, add this to
143
- the corresponding file in config/environments:
144
-
145
- config.after_initialize do
146
- SlavePools.setup!
147
- end
148
-
149
-
150
- === Using with Phusion Passenger
151
-
152
- (this is a note from MultiDB gem and has not been verified)
153
-
154
- With Passengers smart spawning method, child processes forked by the ApplicationSpawner
155
- won't have the connection proxy set up properly (this is a note from ).
156
-
157
- To make it work, add this to your <tt>environment.rb</tt> or an initializer script
158
- (e.g. <tt>config/initializers/connection_proxy.rb</tt>):
159
-
160
- if defined?(PhusionPassenger)
161
- PhusionPassenger.on_event(:starting_worker_process) do |forked|
162
- if forked
163
- # ... set configuration options, if any ...
164
- SlavePools::ConnectionProxy.setup!
165
- end
166
- end
167
- else # not using passenger (e.g. development/testing)
168
- # ... set configuration options, if any ...
169
- SlavePools::ConnectionProxy.setup!
170
- end
171
-
172
- === Using with ThinkingSphinx
173
-
174
- ThinkingSphinx looks for an adapter type and
175
- SlavePools::ConnectionProxy.setup!
176
-
177
- if ActiveRecord::Base.respond_to?('connection_proxy')
178
- ThinkingSphinx::AbstractAdapter.class_eval do
179
- def self.standard_adapter_for_model(model)
180
- :mysql
181
- end
182
- end
183
- end
184
-
185
- === Forcing the master for certain actions
186
-
187
- Just add this to your controller:
188
-
189
- around_filter(:only => :foo_action) { |c,a| ActiveRecord::Base.connection_proxy.with_master { a.call } }
190
-
191
- === Forcing the master for certain models
192
-
193
- In your environment.rb or an initializer, add this *before* the call to <tt>setup!</tt>:
194
-
195
- SlavePoolsModule::ConnectionProxy.master_models = ['CGI::Session::ActiveRecordStore::Session', 'PaymentTransaction', ...]
196
- SlavePoolsModule::ConnectionProxy.setup!
197
-
198
- *NOTE*: You cannot safely add more master_models after calling <tt>setup!</tt>.
199
- === Features
200
- * Minimalist implementation - does include sharding, doesn't creation a new adapter (so if you don't specify slaves for
201
- an environment, the connection is not overwritten, and the DB works as normal), doesn't blacklist/remove slaves,
202
- * It sends everything except "select ..." queries to the master, instead of
203
- sending only specific things to the master and anything "else" to the slave.
204
- This avoids accidental writes to the master when there are API changes in
205
- ActiveRecord which haven't been picked up by multi_db yet.
206
- Note that this behavior will also always send helper methods like "+quote+" or
207
- "<tt>add_limit!</tt>" to the master connection object, which doesn't add any
208
- more load on the master, as these methods don't communicate with the db server
209
- itself.
210
-
211
-
212
- === Differences to "multi_db":
213
-
214
- * Supports multiple separate pools of slave databases
215
- * query caching is fixed
216
- * tries a slave once and immediately reverts to the master afterwards (does not cycle through slaves)
217
- * stays with the same slave DB until explicitly told to change. In practical usage, it didn't make sense to us
218
- to have it cycle through slaves in the same web request, so I made the 'sticky slave' feature permanent
219
- * removed weighted slave rotation for now (didn't need it)
220
- * Currently not using Threaded variables (left this commented out in the code for now, may revisit)
221
- * Added with_pool method
222
- * does not blacklist slaves for timing out (we want other more robust monitoring software to take care of this)
223
- * better default case handling - if no slave DB's are specified, the regular Environment database is used, and the gem is
224
- not initialized
225
- * added a wrapper class for shorter calls
226
-
227
- === See also
228
-
229
- ===== Masochism
230
-
231
- The original master/slave plugin:
232
-
233
- * http://github.com/technoweenie/masochism
234
-
235
- ===== MultiDb
236
-
237
- The project is based on:
238
-
239
- * https://github.com/schoefmax/multi_db
240
-
241
- === Running specs
242
-
243
- If you haven't already, install the rspec gem, then set up your database
244
- with a test database and a read_only user.
245
-
246
- To match spec/config/database.yml, you can:
247
-
248
- mysql>
249
- create database test_db;
250
- create user 'read_only'@'localhost' identified by 'readme';
251
- grant select on db_test.* to 'read_only'@'localhost';
252
-
253
- From the plugin directory, run:
254
-
255
- rspec spec
256
-
257
- Author: Dan Drabik
258
- Copyright (c) 2012, Kickstarter
259
- Released under the MIT license
@@ -1,45 +0,0 @@
1
- module SlavePoolsModule
2
- # Implements the methods expected by the QueryCache module
3
- module QueryCacheCompat
4
-
5
- def select_all(*a, &b)
6
- arel, name, binds = a
7
- if query_cache_enabled && !locked?(arel)
8
- # FIXME this still hits the +select_all+ method in AR connection's
9
- # query_cache.rb. It'd be nice if we could avoid it somehow so
10
- # +select_all+ and then +to_sql+ aren't called redundantly.
11
- sql = to_sql(arel, binds)
12
- @master.connection.send(:cache_sql, sql, binds) {send_to_current(:select_all, *[sql, name, binds], &b)}
13
- else
14
- send_to_current(:select_all, *a, &b)
15
- end
16
- end
17
-
18
- def insert(*a, &b)
19
- @master.connection.clear_query_cache if query_cache_enabled
20
- send_to_master(:insert, *a, &b)
21
- end
22
-
23
- def update(*a, &b)
24
- @master.connection.clear_query_cache if query_cache_enabled
25
- send_to_master(:update, *a, &b)
26
- end
27
-
28
- def delete(*a, &b)
29
- @master.connection.clear_query_cache if query_cache_enabled
30
- send_to_master(:delete, *a, &b)
31
- end
32
-
33
- # Rails 3.2 changed query cacheing a little and affected slave_pools like this:
34
- #
35
- # * ActiveRecord::Base.cache sets @query_cache_enabled for current connection
36
- # * ActiveRecord::QueryCache middleware (in call()) that Rails uses sets
37
- # @query_cache_enabled directly on ActiveRecord::Base.connection
38
- # (which could be master at that point)
39
- #
40
- # :`( So, let's just use the master connection for all query cacheing.
41
- def query_cache_enabled
42
- @master.connection.query_cache_enabled
43
- end
44
- end
45
- end