fresh_connection 0.0.7 → 0.1.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 +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
|
-
|