fresh_connection 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +1 -27
- data/fresh_connection.gemspec +22 -25
- data/lib/fresh_connection/active_record/abstract_adapter.rb +24 -0
- data/lib/fresh_connection/active_record/mysql2_adapter.rb +14 -0
- data/lib/fresh_connection/active_record/relation.rb +22 -0
- data/lib/fresh_connection/railtie.rb +10 -0
- data/lib/fresh_connection/slave_connection.rb +37 -10
- data/lib/fresh_connection/version.rb +4 -0
- data/lib/fresh_connection.rb +5 -5
- metadata +66 -27
- data/History.txt +0 -13
- data/Manifest.txt +0 -9
- data/README.rdoc +0 -60
- data/rails/initializers/active_record_base.rb +0 -109
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bb171789539cc2eaf31793f904e53f4c0a9f1114
|
4
|
+
data.tar.gz: be8ef001eec63ca7a879d3950fb460b7f300bdb6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: becd1aed70d40cecaa8155630609e7ec13d9fd62c4f4ce6fb92e4f6e54bdeb025915aa55dc9deb226da2a89f6c0bfb491353dea84b68595bf015599108c8e238
|
7
|
+
data.tar.gz: 4aa63bc28708181c47df8dfd211e6fceb2df57dc2a45d1e053a0594db9d1b82b6d366c0186c77f17f1b8faa80a5fccd26f4d9aa8fe51a88b9a9b0451aee32fcf
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 tsukasaoishi
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# FreshConnection
|
2
|
+
|
3
|
+
FreshConnection supports to connect with Mysql slave servers via Load Balancers.
|
4
|
+
All connections will be disconnected every time at the end of the action.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
### For Rails3
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem "fresh_connection"
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install fresh_connection
|
20
|
+
|
21
|
+
### For Rails2.3
|
22
|
+
|
23
|
+
$ gem install fresh_connection -v 0.0.7
|
24
|
+
|
25
|
+
## Config
|
26
|
+
#### config/database.yml
|
27
|
+
|
28
|
+
production:
|
29
|
+
adapter: mysql2
|
30
|
+
encoding: utf8
|
31
|
+
reconnect: true
|
32
|
+
database: kaeru
|
33
|
+
pool: 5
|
34
|
+
username: master
|
35
|
+
password: master
|
36
|
+
host: localhost
|
37
|
+
socket: /var/run/mysqld/mysqld.sock
|
38
|
+
|
39
|
+
slave:
|
40
|
+
username: slave
|
41
|
+
password: slave
|
42
|
+
host: slave
|
43
|
+
|
44
|
+
slave is config to connect to slave servers.
|
45
|
+
Others will use the master setting. If you want to change, write in the slave.
|
46
|
+
|
47
|
+
### config/initializers/fresh_connection.rb
|
48
|
+
|
49
|
+
FreshConnection::SlaveConnection.ignore_models = %w|Model1 Model2|
|
50
|
+
|
51
|
+
If models that ignore access to slave servers is exist, You can write model name at FreshConnection::SlaveConnection.ignore models.
|
52
|
+
|
53
|
+
### use config/environment.rb if rails2.3
|
54
|
+
|
55
|
+
require 'fresh_connection'
|
56
|
+
ActionController::Dispatcher.middleware.swap ActiveRecord::ConnectionAdapters::ConnectionManagement, FreshConnection::Rack::ConnectionManagement
|
57
|
+
|
58
|
+
## Usage
|
59
|
+
Read query will be access to slave server.
|
60
|
+
|
61
|
+
Article.where(:id => 1)
|
62
|
+
|
63
|
+
If you want to access to master saver, use readonly(false).
|
64
|
+
|
65
|
+
Article.where(:id => 1).readonly(false)
|
66
|
+
|
67
|
+
In transaction, Always will be access to master server.
|
68
|
+
|
69
|
+
Article.transaction do
|
70
|
+
Article.where(:id => 1)
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
## Contributing
|
75
|
+
|
76
|
+
1. Fork it
|
77
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
78
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
79
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
80
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1,27 +1 @@
|
|
1
|
-
|
2
|
-
require File.dirname(__FILE__) + '/lib/fresh_connection'
|
3
|
-
|
4
|
-
# Generate all the Rake tasks
|
5
|
-
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
-
$hoe = Hoe.new('fresh_connection', FreshConnection::VERSION) do |p|
|
7
|
-
p.developer('Tsukasa OISHI', 'tsukasa.oishi@gmail.com')
|
8
|
-
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
|
-
p.rubyforge_name = p.name # TODO this is default value
|
10
|
-
# p.extra_deps = [
|
11
|
-
# ['activesupport','>= 2.0.2'],
|
12
|
-
# ]
|
13
|
-
p.extra_dev_deps = [
|
14
|
-
['newgem', ">= #{::Newgem::VERSION}"]
|
15
|
-
]
|
16
|
-
|
17
|
-
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
18
|
-
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
19
|
-
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
20
|
-
p.rsync_args = '-av --delete --ignore-errors'
|
21
|
-
end
|
22
|
-
|
23
|
-
require 'newgem/tasks' # load /tasks/*.rake
|
24
|
-
Dir['tasks/**/*.rake'].each { |t| load t }
|
25
|
-
|
26
|
-
# TODO - want other tests/tasks run by default? Add them to the list
|
27
|
-
# task :default => [:spec, :features]
|
1
|
+
require "bundler/gem_tasks"
|
data/fresh_connection.gemspec
CHANGED
@@ -1,28 +1,25 @@
|
|
1
|
-
#
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fresh_connection/version'
|
2
5
|
|
3
|
-
Gem::Specification.new do |
|
4
|
-
|
5
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fresh_connection"
|
8
|
+
spec.version = FreshConnection::VERSION
|
9
|
+
spec.authors = ["Tsukasa OISHI"]
|
10
|
+
spec.email = ["tsukasa.oishi@gmail.com"]
|
11
|
+
spec.description = %q{https://github.com/tsukasaoishi/fresh_connection}
|
12
|
+
spec.summary = %q{FreshConnection supports to connect with Mysql slave servers via Load Balancers.}
|
13
|
+
spec.homepage = "https://github.com/tsukasaoishi/fresh_connection"
|
14
|
+
spec.license = "MIT"
|
6
15
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
lib/fresh_connection.rb
|
17
|
-
lib/fresh_connection/slave_connection.rb
|
18
|
-
lib/fresh_connection/rack/connection_management.rb
|
19
|
-
rails/initializers/active_record_base.rb
|
20
|
-
|
|
21
|
-
s.has_rdoc = true
|
22
|
-
s.homepage = %q{https://github.com/tsukasaoishi/fresh_connection}
|
23
|
-
s.rdoc_options = ["--main", "README.rdoc"]
|
24
|
-
s.require_paths = ["lib"]
|
25
|
-
s.rubyforge_project = %q{fresh_connection}
|
26
|
-
s.rubygems_version = %q{1.3.1}
|
27
|
-
s.summary = %q{FreshConnection supports of connect with Mysql slave servers via Load Balancers.}
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'activerecord', '~> 3.2.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
28
25
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class AbstractAdapter
|
4
|
+
def select_all_with_slave_connection(arel, name = nil, binds = [])
|
5
|
+
if FreshConnection::SlaveConnection.slave_access?
|
6
|
+
change_connection {select_all_without_slave_connection(arel, "[slave] #{name}", binds)}
|
7
|
+
else
|
8
|
+
select_all_without_slave_connection(arel, name, binds)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
alias_method_chain :select_all, :slave_connection
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def change_connection
|
16
|
+
master_con, @connection =
|
17
|
+
@connection, FreshConnection::SlaveConnection.connection.raw_connection
|
18
|
+
yield
|
19
|
+
ensure
|
20
|
+
@connection = master_con
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'active_record/connection_adapters/mysql2_adapter'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
class Mysql2Adapter < AbstractMysqlAdapter
|
6
|
+
private
|
7
|
+
|
8
|
+
def configure_connection_with_ignore
|
9
|
+
configure_connection_without_ignore unless FreshConnection::SlaveConnection.ignore_configure_connection?
|
10
|
+
end
|
11
|
+
alias_method_chain :configure_connection, :ignore
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
class Relation
|
3
|
+
private
|
4
|
+
|
5
|
+
def exec_queries_with_slave_connection
|
6
|
+
return @records if loaded?
|
7
|
+
|
8
|
+
if FreshConnection::SlaveConnection.ignore_model?(@klass.name)
|
9
|
+
FreshConnection::SlaveConnection.force_master_access { exec_queries_without_slave_connection }
|
10
|
+
elsif go_slave?
|
11
|
+
FreshConnection::SlaveConnection.slave_access { exec_queries_without_slave_connection }
|
12
|
+
else
|
13
|
+
FreshConnection::SlaveConnection.master_access { exec_queries_without_slave_connection }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
alias_method_chain :exec_queries, :slave_connection
|
17
|
+
|
18
|
+
def go_slave?
|
19
|
+
connection.open_transactions == 0 && (@readonly_value.nil? || @readonly_value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module FreshConnection
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer "fresh_connection.configure_rails_initialization" do |app|
|
4
|
+
app.config.middleware.swap(
|
5
|
+
ActiveRecord::ConnectionAdapters::ConnectionManagement,
|
6
|
+
FreshConnection::Rack::ConnectionManagement
|
7
|
+
)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module FreshConnection
|
2
2
|
class SlaveConnection
|
3
|
+
COUNT = :fresh_connection_access_count
|
4
|
+
TARGET = :fresh_connection_access_target
|
5
|
+
|
3
6
|
class << self
|
4
7
|
attr_writer :ignore_models, :ignore_configure_connection, :master_clear_connection
|
5
8
|
|
@@ -14,16 +17,30 @@ module FreshConnection
|
|
14
17
|
@slave_connections = {}
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
|
20
|
+
def slave_access
|
21
|
+
access_in(:slave)
|
22
|
+
yield
|
23
|
+
ensure
|
24
|
+
access_out
|
25
|
+
end
|
26
|
+
|
27
|
+
def master_access
|
28
|
+
access_in(:master)
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
access_out
|
19
32
|
end
|
20
33
|
|
21
|
-
def
|
22
|
-
Thread.current[
|
34
|
+
def force_master_access
|
35
|
+
now_target = Thread.current[TARGET]
|
36
|
+
Thread.current[TARGET] = :master
|
37
|
+
yield
|
38
|
+
ensure
|
39
|
+
Thread.current[TARGET] = now_target
|
23
40
|
end
|
24
41
|
|
25
42
|
def slave_access?
|
26
|
-
Thread.current[
|
43
|
+
Thread.current[TARGET] == :slave
|
27
44
|
end
|
28
45
|
|
29
46
|
def ignore_model?(model_name)
|
@@ -35,20 +52,30 @@ module FreshConnection
|
|
35
52
|
end
|
36
53
|
|
37
54
|
def master_clear_connection?
|
38
|
-
@master_clear_connection
|
55
|
+
@master_clear_connection || false
|
39
56
|
end
|
40
57
|
|
41
58
|
private
|
42
59
|
|
60
|
+
def access_in(target)
|
61
|
+
Thread.current[COUNT] = (Thread.current[COUNT] || 0) + 1
|
62
|
+
Thread.current[TARGET] ||= target
|
63
|
+
end
|
64
|
+
|
65
|
+
def access_out
|
66
|
+
Thread.current[COUNT] -= 1
|
67
|
+
if Thread.current[COUNT] == 0
|
68
|
+
Thread.current[TARGET] = nil
|
69
|
+
Thread.current[COUNT] = nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
43
74
|
def slave_connection
|
44
75
|
@slave_connections ||= {}
|
45
76
|
@slave_connections[current_thread_id] ||= new_connection
|
46
77
|
end
|
47
78
|
|
48
|
-
def clear_slave_connection
|
49
|
-
@slave_connections[current_thread_id] = nil
|
50
|
-
end
|
51
|
-
|
52
79
|
def new_connection
|
53
80
|
ActiveRecord::Base.send("#{spec["adapter"]}_connection", spec)
|
54
81
|
end
|
data/lib/fresh_connection.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0.5"
|
3
|
-
end
|
4
|
-
|
1
|
+
require "fresh_connection/version"
|
5
2
|
require "fresh_connection/slave_connection"
|
6
3
|
require "fresh_connection/rack/connection_management"
|
4
|
+
require "fresh_connection/active_record/relation"
|
5
|
+
require "fresh_connection/active_record/abstract_adapter"
|
6
|
+
require "fresh_connection/active_record/mysql2_adapter"
|
7
7
|
|
8
|
-
|
8
|
+
require "fresh_connection/railtie.rb" if defined?(Rails)
|
metadata
CHANGED
@@ -1,60 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fresh_connection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Tsukasa OISHI
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
|
15
|
-
|
11
|
+
date: 2013-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.2.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: https://github.com/tsukasaoishi/fresh_connection
|
16
56
|
email:
|
17
57
|
- tsukasa.oishi@gmail.com
|
18
58
|
executables: []
|
19
59
|
extensions: []
|
20
|
-
extra_rdoc_files:
|
21
|
-
- History.txt
|
22
|
-
- Manifest.txt
|
23
|
-
- README.rdoc
|
60
|
+
extra_rdoc_files: []
|
24
61
|
files:
|
62
|
+
- Gemfile
|
63
|
+
- LICENSE.txt
|
64
|
+
- README.md
|
25
65
|
- Rakefile
|
26
66
|
- fresh_connection.gemspec
|
27
67
|
- lib/fresh_connection.rb
|
28
|
-
- lib/fresh_connection/
|
68
|
+
- lib/fresh_connection/active_record/abstract_adapter.rb
|
69
|
+
- lib/fresh_connection/active_record/mysql2_adapter.rb
|
70
|
+
- lib/fresh_connection/active_record/relation.rb
|
29
71
|
- lib/fresh_connection/rack/connection_management.rb
|
30
|
-
-
|
31
|
-
-
|
32
|
-
-
|
33
|
-
- README.rdoc
|
72
|
+
- lib/fresh_connection/railtie.rb
|
73
|
+
- lib/fresh_connection/slave_connection.rb
|
74
|
+
- lib/fresh_connection/version.rb
|
34
75
|
homepage: https://github.com/tsukasaoishi/fresh_connection
|
35
|
-
licenses:
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
36
79
|
post_install_message:
|
37
|
-
rdoc_options:
|
38
|
-
- --main
|
39
|
-
- README.rdoc
|
80
|
+
rdoc_options: []
|
40
81
|
require_paths:
|
41
82
|
- lib
|
42
83
|
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
84
|
requirements:
|
45
|
-
- -
|
85
|
+
- - '>='
|
46
86
|
- !ruby/object:Gem::Version
|
47
87
|
version: '0'
|
48
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
89
|
requirements:
|
51
|
-
- -
|
90
|
+
- - '>='
|
52
91
|
- !ruby/object:Gem::Version
|
53
92
|
version: '0'
|
54
93
|
requirements: []
|
55
|
-
rubyforge_project:
|
56
|
-
rubygems_version:
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 2.0.0
|
57
96
|
signing_key:
|
58
|
-
specification_version:
|
59
|
-
summary: FreshConnection supports
|
97
|
+
specification_version: 4
|
98
|
+
summary: FreshConnection supports to connect with Mysql slave servers via Load Balancers.
|
60
99
|
test_files: []
|
data/History.txt
DELETED
data/Manifest.txt
DELETED
data/README.rdoc
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
= FreshConnection
|
2
|
-
|
3
|
-
* https://github.com/tsukasaoishi/fresh_connection
|
4
|
-
|
5
|
-
== Description
|
6
|
-
|
7
|
-
FreshConnection supports of connect with Mysql slave servers via Load Balancers.
|
8
|
-
Currently, I have only tested with Rails2.3.14.
|
9
|
-
In the future, I plan to support Rails3.
|
10
|
-
|
11
|
-
All connections will be disconnected every time at the end of the action.
|
12
|
-
|
13
|
-
== How to use at Rails
|
14
|
-
|
15
|
-
=== Gemfile
|
16
|
-
gem "fresh_connection", "=0.0.2"
|
17
|
-
|
18
|
-
=== config/database.yml
|
19
|
-
production:
|
20
|
-
adapter: mysql
|
21
|
-
encoding: utf8
|
22
|
-
reconnect: true
|
23
|
-
database: kaeru
|
24
|
-
pool: 5
|
25
|
-
username: master
|
26
|
-
password: master
|
27
|
-
host: localhost
|
28
|
-
socket: /var/run/mysqld/mysqld.sock
|
29
|
-
|
30
|
-
slave:
|
31
|
-
username: slave
|
32
|
-
password: slave
|
33
|
-
host: slave
|
34
|
-
|
35
|
-
slave is config to connect to slave servers.
|
36
|
-
Others will use the master setting. If you want to change, write in the slave.
|
37
|
-
|
38
|
-
|
39
|
-
=== config/environment.rb
|
40
|
-
require 'fresh_connection'
|
41
|
-
ActionController::Dispatcher.middleware.swap ActiveRecord::ConnectionAdapters::ConnectionManagement, FreshConnection::Rack::ConnectionManagement
|
42
|
-
|
43
|
-
=== config/initializers/fresh_connection.rb
|
44
|
-
FreshConnection::SlaveConnection.ignore_models = %w|Model1 Model2|
|
45
|
-
|
46
|
-
If models that ignore access to slave servers is exist, You can write model name at FreshConnection::SlaveConnection.ignore_models.
|
47
|
-
|
48
|
-
== Synopis
|
49
|
-
Read query will be access to slave server.
|
50
|
-
Article.where(:id => 1)
|
51
|
-
|
52
|
-
If you want to access to master saver, use readonly(false).
|
53
|
-
Article.where(:id => 1).readonly(false)
|
54
|
-
|
55
|
-
In transaction, Always will be access to master server.
|
56
|
-
Article.transaction do
|
57
|
-
Article.where(:id => 1)
|
58
|
-
end
|
59
|
-
|
60
|
-
|
@@ -1,109 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module ConnectionAdapters
|
3
|
-
class AbstractAdapter
|
4
|
-
def select_all_with_slave_cluster(*args)
|
5
|
-
if FreshConnection::SlaveConnection.slave_access?
|
6
|
-
change_connection {select_all_without_slave_cluster(*args)}
|
7
|
-
else
|
8
|
-
select_all_without_slave_cluster(*args)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
alias_method_chain :select_all, :slave_cluster
|
12
|
-
|
13
|
-
def columns_with_slave_cluster(*args)
|
14
|
-
if FreshConnection::SlaveConnection.slave_access?
|
15
|
-
change_connection {columns_without_slave_cluster(*args)}
|
16
|
-
else
|
17
|
-
columns_without_slave_cluster(*args)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
alias_method_chain :columns, :slave_cluster
|
21
|
-
|
22
|
-
def log_info_with_slave_cluster(sql, name, ms)
|
23
|
-
name = "[MASTER] " + (name || "SQL") if !FreshConnection::SlaveConnection.slave_access? && name != "CACHE"
|
24
|
-
log_info_without_slave_cluster(sql, name, ms)
|
25
|
-
end
|
26
|
-
alias_method_chain :log_info, :slave_cluster
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def change_connection
|
31
|
-
master_con, @connection = @connection, FreshConnection::SlaveConnection.connection.raw_connection
|
32
|
-
yield
|
33
|
-
ensure
|
34
|
-
@connection = master_con
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class MysqlAdapter < AbstractAdapter
|
39
|
-
private
|
40
|
-
|
41
|
-
def configure_connection_with_ignore
|
42
|
-
configure_connection_without_ignore unless FreshConnection::SlaveConnection.ignore_configure_connection?
|
43
|
-
end
|
44
|
-
alias_method_chain :configure_connection, :ignore
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class Base
|
49
|
-
class << self
|
50
|
-
def find_every_with_slave_cluster(options)
|
51
|
-
run_on_db(options) { find_every_without_slave_cluster(options) }
|
52
|
-
end
|
53
|
-
alias_method_chain :find_every, :slave_cluster
|
54
|
-
|
55
|
-
def find_by_sql_with_slave_cluster(sql, options = nil)
|
56
|
-
run_on_db(options) { find_by_sql_without_slave_cluster(sql) }
|
57
|
-
end
|
58
|
-
alias_method_chain :find_by_sql, :slave_cluster
|
59
|
-
|
60
|
-
def count_by_sql_with_slave_cluster(sql, options = nil)
|
61
|
-
run_on_db(options) { count_by_sql_without_slave_cluster(sql) }
|
62
|
-
end
|
63
|
-
alias_method_chain :count_by_sql, :slave_cluster
|
64
|
-
|
65
|
-
def calculate_with_slave_cluster(operation, column_name, options = {})
|
66
|
-
run_on_db(options) do
|
67
|
-
options.delete(:readonly)
|
68
|
-
calculate_without_slave_cluster(operation, column_name, options)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
alias_method_chain :calculate, :slave_cluster
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
def run_on_db(options)
|
76
|
-
in_run_on_db(options)
|
77
|
-
run_on_db_status[:go_slave] ? run_on_readonly_db{yield} : yield
|
78
|
-
ensure
|
79
|
-
out_run_on_db
|
80
|
-
end
|
81
|
-
|
82
|
-
def in_run_on_db(options)
|
83
|
-
run_on_db_status[:go_slave] = go_slave?(options) if run_on_db_status[:count] == 0
|
84
|
-
run_on_db_status[:count] += 1
|
85
|
-
end
|
86
|
-
|
87
|
-
def out_run_on_db
|
88
|
-
run_on_db_status[:count] -= 1
|
89
|
-
end
|
90
|
-
|
91
|
-
def run_on_db_status
|
92
|
-
Thread.current[:run_on_db_status] ||= {:count => 0, :go_slave => false}
|
93
|
-
end
|
94
|
-
|
95
|
-
def go_slave?(options)
|
96
|
-
!FreshConnection::SlaveConnection.ignore_model?(self.name) && connection.open_transactions == 0 &&
|
97
|
-
(!options.is_a?(Hash) || !options.key?(:readonly) || options[:readonly].nil? || options[:readonly])
|
98
|
-
end
|
99
|
-
|
100
|
-
def run_on_readonly_db
|
101
|
-
FreshConnection::SlaveConnection.slave_access_in
|
102
|
-
yield
|
103
|
-
ensure
|
104
|
-
FreshConnection::SlaveConnection.slave_access_out
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|