postamt 0.9.0 → 0.9.1
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +53 -2
- data/lib/postamt.rb +33 -9
- data/lib/postamt/railtie.rb +17 -2
- data/lib/postamt/version.rb +1 -1
- data/postamt.gemspec +3 -3
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0735b7ec645e87e9007592822f3e14bca2f4e810
|
4
|
+
data.tar.gz: 8b3f02abb5439a16c536fd3608c8d53147bc5f3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cf4b7e33e840638afa19a8fe57c49d4221f4974ff4407119fb7811d9b5b53eec0936298f9669dd34f38819a4c6b4d4b15afacfa8746eded03b505d75916bf25
|
7
|
+
data.tar.gz: a1cd70c63e0565966c399bdd52faecec71cfa932fd6948e4b491f76efb457713f3c02b5ef2df13102c864ed089c457ca684a2d40b8fc7b57f0790241edce516f
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,12 +1,31 @@
|
|
1
1
|
# Postamt
|
2
2
|
|
3
|
-
|
3
|
+
[](http://rubygems.org/gems/postamt)
|
4
|
+
|
5
|
+
Postamt is a sane, Rails-4-ready solution for performing database
|
6
|
+
reads against a hot standby server.
|
7
|
+
|
8
|
+
Choose per model and/or controller&action whether a read-only query
|
9
|
+
should be sent to master or a hot standby.<br />
|
10
|
+
Inside a transaction reads always happen against master.
|
11
|
+
|
12
|
+
Care has been taken to avoid [common performance
|
13
|
+
pitfalls](http://charlie.bz/blog/things-that-clear-rubys-method-cache).
|
14
|
+
It's been battle tested in production at
|
15
|
+
[sauspiel.de](https://www.sauspiel.de/).
|
16
|
+
|
17
|
+
Monkey-patching is kept to an absolute minimum, the hard work happens
|
18
|
+
through [officially-supported Rails
|
19
|
+
APIs](https://github.com/rails/rails/commit/ba1544d71628abff2777c9c514142d7e9a159111#commitcomment-2106059).
|
20
|
+
That's why there's so little code compared to similar gems.
|
21
|
+
|
22
|
+
Postamt requires Rails 3.2+ and works with Rails 4.
|
4
23
|
|
5
24
|
## Installation
|
6
25
|
|
7
26
|
Add this line to your application's Gemfile:
|
8
27
|
|
9
|
-
gem '
|
28
|
+
gem 'postamt'
|
10
29
|
|
11
30
|
## Example usage
|
12
31
|
|
@@ -81,6 +100,37 @@ end
|
|
81
100
|
Postamt.force_connection = :master
|
82
101
|
```
|
83
102
|
|
103
|
+
## Tests
|
104
|
+
|
105
|
+
Create the DB `postamt_test` and ensure the users `master` and
|
106
|
+
`slave` exist:
|
107
|
+
|
108
|
+
```
|
109
|
+
$ createdb postamt_test
|
110
|
+
$ createuser -s master # -s => superuser
|
111
|
+
$ createuser -s slave # better to restrict slave to be read-only
|
112
|
+
```
|
113
|
+
|
114
|
+
Migrate the DB in the Rails 4 app:
|
115
|
+
|
116
|
+
```
|
117
|
+
$ cd testapp # Rails 4
|
118
|
+
$ RAILS_ENV=test bundle exec rake db:migrate
|
119
|
+
```
|
120
|
+
|
121
|
+
Run the tests on Rails 3.2 and Rails 4:
|
122
|
+
|
123
|
+
```
|
124
|
+
$ cd testapp # Rails 4
|
125
|
+
$ bundle exec ruby -Itest test/integration/postamt_test.rb
|
126
|
+
$ cd testapp32 # Rails 3.2
|
127
|
+
$ bundle exec ruby -Itest test/integration/postamt_test.rb
|
128
|
+
```
|
129
|
+
|
130
|
+
You can't run the tests via a simple `rake` because Postamt deactivates
|
131
|
+
itself when it detects that a task starting with 'db' is run (like
|
132
|
+
`db:test:prepare`)
|
133
|
+
|
84
134
|
## Contributing
|
85
135
|
|
86
136
|
1. Fork it
|
@@ -88,3 +138,4 @@ Postamt.force_connection = :master
|
|
88
138
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
89
139
|
4. Push to the branch (`git push origin my-new-feature`)
|
90
140
|
5. Create new Pull Request
|
141
|
+
|
data/lib/postamt.rb
CHANGED
@@ -42,7 +42,7 @@ module Postamt
|
|
42
42
|
Thread.current[:postamt_overwritten_default_connections] ||= {}
|
43
43
|
end
|
44
44
|
|
45
|
-
if Rails::VERSION::MAJOR == 4 and Rails::VERSION::MINOR
|
45
|
+
if Rails::VERSION::MAJOR == 4 and Rails::VERSION::MINOR <= 1
|
46
46
|
Postamt::ConnectionSpecificationResolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver
|
47
47
|
elsif Rails::VERSION::MAJOR == 3 and Rails::VERSION::MINOR == 2
|
48
48
|
Postamt::ConnectionSpecificationResolver = ActiveRecord::Base::ConnectionSpecification::Resolver
|
@@ -52,7 +52,7 @@ module Postamt
|
|
52
52
|
|
53
53
|
# Called by Postamt::Railtie
|
54
54
|
def self.hook!
|
55
|
-
if Rails::VERSION::MAJOR == 4 and Rails::VERSION::MINOR
|
55
|
+
if Rails::VERSION::MAJOR == 4 and Rails::VERSION::MINOR <= 1
|
56
56
|
ActiveRecord::Base.default_connection_handler = Postamt::ConnectionHandler.new
|
57
57
|
elsif Rails::VERSION::MAJOR == 3 and Rails::VERSION::MINOR == 2
|
58
58
|
ActiveRecord::Base.connection_handler = Postamt::ConnectionHandler.new
|
@@ -96,16 +96,40 @@ module Postamt
|
|
96
96
|
alias_method_chain :update_all, :postamt
|
97
97
|
end
|
98
98
|
|
99
|
+
ActiveRecord::LogSubscriber.class_eval do
|
100
|
+
attr_accessor :connection_name
|
101
|
+
|
102
|
+
def sql_with_connection_name(event)
|
103
|
+
self.connection_name = ObjectSpace._id2ref(event.payload[:connection_id]).instance_variable_get(:@config)[:username]
|
104
|
+
sql_without_connection_name(event)
|
105
|
+
end
|
106
|
+
|
107
|
+
def debug_with_connection_name(msg)
|
108
|
+
conn = connection_name ? color(" [#{connection_name}]", ActiveSupport::LogSubscriber::BLUE, true) : ''
|
109
|
+
debug_without_connection_name(conn + msg)
|
110
|
+
end
|
111
|
+
|
112
|
+
# TODO: Switch to Module#prepend once we are Ruby-2.0.0-onlhy
|
113
|
+
alias_method_chain :sql, :connection_name
|
114
|
+
alias_method_chain :debug, :connection_name
|
115
|
+
end
|
116
|
+
|
99
117
|
ActionController::Base.instance_eval do
|
100
118
|
def use_db_connection(connection, args)
|
101
|
-
default_connections = {}
|
102
119
|
klass_names = args.delete(:for)
|
103
|
-
klass_names
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
120
|
+
if klass_names == :all
|
121
|
+
around_filter(args) do |controller|
|
122
|
+
Postamt.on(connection) { yield }
|
123
|
+
end
|
124
|
+
else
|
125
|
+
default_connections = {}
|
126
|
+
klass_names.each do |klass_name|
|
127
|
+
default_connections[klass_name] = connection
|
128
|
+
end
|
129
|
+
|
130
|
+
before_filter(args) do |controller|
|
131
|
+
Postamt.overwritten_default_connections.merge!(default_connections)
|
132
|
+
end
|
109
133
|
end
|
110
134
|
end
|
111
135
|
|
data/lib/postamt/railtie.rb
CHANGED
@@ -2,8 +2,13 @@ module Postamt
|
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
railtie_name "postamt"
|
4
4
|
|
5
|
+
attr_accessor :running_in_rake
|
6
|
+
rake_tasks do
|
7
|
+
self.running_in_rake = true
|
8
|
+
end
|
9
|
+
|
5
10
|
initializer "postamt.hook", before: "active_record.initialize_database" do |app|
|
6
|
-
if
|
11
|
+
if self.running_in_rake
|
7
12
|
# We mustn't hook into AR when db:migrate or db:test:load_schema
|
8
13
|
# run, but user-defined Rake tasks still need us
|
9
14
|
task_names = []
|
@@ -13,7 +18,17 @@ module Postamt
|
|
13
18
|
task_names << task.name
|
14
19
|
tasks_to_examine += task.prerequisite_tasks
|
15
20
|
end
|
16
|
-
|
21
|
+
if task_names.any? { |task_name| task_name.start_with? "db:" }
|
22
|
+
# Stub out Postamt's monkeypatches if we're running in a Rake task
|
23
|
+
ActionController::Base.instance_eval do
|
24
|
+
def use_db_connection(connection, args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
ActiveRecord::Base.instance_eval do
|
28
|
+
class_attribute :default_connection
|
29
|
+
end
|
30
|
+
next
|
31
|
+
end
|
17
32
|
end
|
18
33
|
Postamt.hook!
|
19
34
|
end
|
data/lib/postamt/version.rb
CHANGED
data/postamt.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'postamt/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "postamt"
|
8
8
|
spec.version = Postamt::VERSION
|
9
|
-
spec.authors = ["Martin Schürrer"]
|
10
|
-
spec.email = ["martin@schuerrer.org"]
|
9
|
+
spec.authors = ["Martin Schürrer", "Martin Kavalar"]
|
10
|
+
spec.email = ["martin@schuerrer.org", "martin@sauspiel.de"]
|
11
11
|
spec.description = %q{Choose per model and/or controller&action whether a read-only query should be sent to master or a hot standby. Or just use Postamt.on(:slave) { ... }. }
|
12
12
|
spec.summary = %q{Performs (some of) your read-only queries on a hot standby}
|
13
13
|
spec.homepage = "https://github.com/sauspiel/postamt"
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "thread_safe", "~> 0.1"
|
22
|
-
spec.add_dependency "railties", [">= 3.2.0", "
|
22
|
+
spec.add_dependency "railties", [">= 3.2.0", "<= 4.1.0"]
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
24
|
spec.add_development_dependency "rake"
|
25
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postamt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Schürrer
|
8
|
+
- Martin Kavalar
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2014-01-06 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: thread_safe
|
@@ -31,7 +32,7 @@ dependencies:
|
|
31
32
|
- - '>='
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: 3.2.0
|
34
|
-
- -
|
35
|
+
- - <=
|
35
36
|
- !ruby/object:Gem::Version
|
36
37
|
version: 4.1.0
|
37
38
|
type: :runtime
|
@@ -41,7 +42,7 @@ dependencies:
|
|
41
42
|
- - '>='
|
42
43
|
- !ruby/object:Gem::Version
|
43
44
|
version: 3.2.0
|
44
|
-
- -
|
45
|
+
- - <=
|
45
46
|
- !ruby/object:Gem::Version
|
46
47
|
version: 4.1.0
|
47
48
|
- !ruby/object:Gem::Dependency
|
@@ -77,11 +78,13 @@ description: 'Choose per model and/or controller&action whether a read-only quer
|
|
77
78
|
}. '
|
78
79
|
email:
|
79
80
|
- martin@schuerrer.org
|
81
|
+
- martin@sauspiel.de
|
80
82
|
executables: []
|
81
83
|
extensions: []
|
82
84
|
extra_rdoc_files: []
|
83
85
|
files:
|
84
86
|
- .gitignore
|
87
|
+
- CHANGELOG.md
|
85
88
|
- Gemfile
|
86
89
|
- LICENSE.txt
|
87
90
|
- README.md
|
@@ -111,9 +114,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
114
|
version: '0'
|
112
115
|
requirements: []
|
113
116
|
rubyforge_project:
|
114
|
-
rubygems_version: 2.0.
|
117
|
+
rubygems_version: 2.0.14
|
115
118
|
signing_key:
|
116
119
|
specification_version: 4
|
117
120
|
summary: Performs (some of) your read-only queries on a hot standby
|
118
121
|
test_files: []
|
119
|
-
has_rdoc:
|