slavery 2.1.0 → 2.1.1

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: 5346c12e4fcf3eaad7b55ce70ca0ffea79f33fe0
4
- data.tar.gz: 74b684b645a28770ecb4d8ae08f6bd5b8daaf7b3
3
+ metadata.gz: 02a75efbc26dd3232de851d07d1903f8808c0afe
4
+ data.tar.gz: 1c6bea05c62d6f8806e45b2e853ea5a78e05f70b
5
5
  SHA512:
6
- metadata.gz: 7b9d823e65b28450161595daaef467bc96dc819ed38c4f2d8e9ea663958fca628dd59942700ad829a36903b415088c3ee07ac0df80f3b81e52fd463f588862b2
7
- data.tar.gz: ff44e84b3580ce6bccafe3d42ca0b00a07dfb6d83bce83be21bce320c3c2df1b3ab2b4de430612332a0136d072f64ffea0b1ca52cac0d0ac7e41a631efcdffcb
6
+ metadata.gz: 4e9f079b232c11fc516e14d849a48f8f7de7cd00149fdf8efa951340d76a10f4c0db4b337ce602d5883212f7186d531198a60bb7a33398170dd95231301f19a6
7
+ data.tar.gz: e82e262252ab96f041f5e47766e78200e0845ba0af7983910cb6b833d0af743be6525e04bb0c7cfad0c8e0d5ed045c083aa602fd4a392c2a16ea5df5c55f6175
data/README.md CHANGED
@@ -123,13 +123,27 @@ It is a good idea to confirm this behavior in your test code as well.
123
123
  You can quickly disable slave reads by dropping the following line in `config/initializers/slavery.rb`.
124
124
 
125
125
  ```ruby
126
- Slavely.disabled = true
126
+ Slavery.disabled = true
127
127
  ```
128
128
 
129
129
  With this line, Slavery stops connection switching and all queries go to the master.
130
130
 
131
131
  This may be useful when one of the master or the slave goes down. You would rewrite `database.yml` to make all queries go to the surviving database, until you restore or rebuild the failed one.
132
132
 
133
+ ## Transactional fixtures
134
+
135
+ When `use_transactional_fixtures` is set to `true`, it's NOT recommended to
136
+ write to the database besides fixtures, since the slave connection is not aware
137
+ of changes performed in the master connection due to [transaction isolation](https://en.wikipedia.org/wiki/Isolation_(database_systems)).
138
+
139
+ In that case, you are suggested to disable Slavery in the test environment by
140
+ putting the following in `test/test_helper.rb`
141
+ (or `spec/spec_helper.rb` for RSpec users):
142
+
143
+ ```ruby
144
+ Slavery.disabled = true
145
+ ```
146
+
133
147
  ## Support for non-Rails apps
134
148
 
135
149
  If you're using ActiveRecord in a non-Rails app (e.g. Sinatra), be sure to set `RACK_ENV` environment variable in the boot sequence, then:
@@ -2,4 +2,7 @@
2
2
 
3
3
  require_relative "../spec/spec_helper"
4
4
  require "irb"
5
+
6
+ ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
7
+
5
8
  IRB.start
@@ -11,11 +11,11 @@ module Slavery
11
11
  private
12
12
 
13
13
  def decide_with(target)
14
- raise Slavery::Error.new('on_slave cannot be used inside transaction block!') if inside_transaction?
15
-
16
14
  if Slavery.disabled
17
15
  :master
18
16
  else
17
+ raise Slavery::Error.new('on_slave cannot be used inside transaction block!') if inside_transaction?
18
+
19
19
  target
20
20
  end
21
21
  end
@@ -1,18 +1,29 @@
1
1
  module Slavery
2
2
  class Transaction
3
+ # The methods on ActiveSupport::TestCase which can potentially be used
4
+ # to determine if transactional fixtures are enabled
5
+ TEST_CONFIG_METHODS = [
6
+ :use_transactional_tests,
7
+ :use_transactional_fixtures
8
+ ]
9
+
3
10
  class << self
4
11
  def base_depth
5
- @base_depth ||= begin
6
- testcase = ActiveSupport::TestCase
7
- if defined?(testcase) &&
8
- testcase.respond_to?(:use_transactional_fixtures) &&
9
- testcase.try(:use_transactional_fixtures)
10
- 1
11
- else
12
- 0
13
- end
12
+ @base_depth ||= if defined?(ActiveSupport::TestCase) &&
13
+ transactional_fixtures_enabled?
14
+ then
15
+ 1
16
+ else
17
+ 0
14
18
  end
15
19
  end
20
+
21
+ private
22
+
23
+ def transactional_fixtures_enabled?
24
+ config = ActiveSupport::TestCase
25
+ TEST_CONFIG_METHODS.any? {|m| config.respond_to?(m) and config.send(m) }
26
+ end
16
27
  end
17
28
  end
18
29
  end
@@ -1,3 +1,3 @@
1
1
  module Slavery
2
- VERSION = '2.1.0'
2
+ VERSION = '2.1.1'
3
3
  end
@@ -10,10 +10,11 @@ describe ActiveRecord::LogSubscriber do
10
10
 
11
11
  before do
12
12
  ActiveRecord::Base.logger = logger
13
+ @backup_disabled = Slavery.disabled
13
14
  end
14
15
 
15
16
  after do
16
- Slavery.disabled = false
17
+ Slavery.disabled = @backup_disabled
17
18
  end
18
19
 
19
20
  it 'it prefixes log messages with master' do
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'configuration' do
4
+ before do
5
+ # Backup connection and configs
6
+ @backup_conn = Slavery.instance_variable_get :@connection_holder
7
+ @backup_config = ActiveRecord::Base.configurations.dup
8
+ @backup_disabled = Slavery.disabled
9
+ Slavery.instance_variable_set :@connection_holder, nil
10
+ end
11
+
12
+ after do
13
+ # Restore connection and configs
14
+ Slavery.instance_variable_set :@connection_holder, @backup_conn
15
+ ActiveRecord::Base.configurations = @backup_config
16
+ Slavery.disabled = @backup_disabled
17
+ end
18
+
19
+ it 'raises error if slave configuration not specified' do
20
+ ActiveRecord::Base.configurations['test_slave'] = nil
21
+
22
+ expect { Slavery.on_slave { User.count } }.to raise_error(Slavery::Error)
23
+ end
24
+
25
+ it 'connects to master if slave configuration not specified' do
26
+ ActiveRecord::Base.configurations['test_slave'] = nil
27
+ Slavery.disabled = true
28
+
29
+ expect(Slavery.on_slave { User.count }).to be 2
30
+ end
31
+
32
+ it 'connects to slave when specified as a hash' do
33
+ Slavery.spec_key = 'test_slave'
34
+ hash = ActiveRecord::Base.configurations['test_slave']
35
+ expect(Slavery::ConnectionHolder).to receive(:establish_connection).with(hash)
36
+ Slavery::ConnectionHolder.activate
37
+ end
38
+
39
+ it 'connects to slave when specified as a url' do
40
+ expected = if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.1.0')
41
+ 'postgres://root:@localhost:5432/test_slave'
42
+ else
43
+ {
44
+ 'adapter' => 'postgresql',
45
+ 'username' => 'root',
46
+ 'host' => 'localhost',
47
+ 'port' => 5432,
48
+ 'database' => 'test_slave'
49
+ }
50
+ end
51
+ Slavery.spec_key = 'test_slave_url'
52
+ expect(Slavery::ConnectionHolder).to receive(:establish_connection).with(expected)
53
+ Slavery::ConnectionHolder.activate
54
+ end
55
+ end
@@ -91,58 +91,4 @@ describe Slavery do
91
91
  expect(User.where(nil).to_a.size).to be 2
92
92
  expect(User.on_slave.where(nil).to_a.size).to be 1
93
93
  end
94
-
95
- describe 'configuration' do
96
- before do
97
- # Backup connection and configs
98
- @backup_conn = Slavery.instance_variable_get :@connection_holder
99
- @backup_config = ActiveRecord::Base.configurations.dup
100
- @backup_disabled = Slavery.disabled
101
- Slavery.instance_variable_set :@connection_holder, nil
102
- end
103
-
104
- after do
105
- # Restore connection and configs
106
- Slavery.instance_variable_set :@connection_holder, @backup_conn
107
- ActiveRecord::Base.configurations = @backup_config
108
- Slavery.disabled = @backup_disabled
109
- end
110
-
111
- it 'raises error if slave configuration not specified' do
112
- ActiveRecord::Base.configurations['test_slave'] = nil
113
-
114
- expect { Slavery.on_slave { User.count } }.to raise_error(Slavery::Error)
115
- end
116
-
117
- it 'connects to master if slave configuration not specified' do
118
- ActiveRecord::Base.configurations['test_slave'] = nil
119
- Slavery.disabled = true
120
-
121
- expect(Slavery.on_slave { User.count }).to be 2
122
- end
123
-
124
- it 'connects to slave when specified as a hash' do
125
- Slavery.spec_key = 'test_slave'
126
- hash = ActiveRecord::Base.configurations['test_slave']
127
- expect(Slavery::ConnectionHolder).to receive(:establish_connection).with(hash)
128
- Slavery::ConnectionHolder.activate
129
- end
130
-
131
- it 'connects to slave when specified as a url' do
132
- expected = if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('4.1.0')
133
- 'postgres://root:@localhost:5432/test_slave'
134
- else
135
- {
136
- 'adapter' => 'postgresql',
137
- 'username' => 'root',
138
- 'port' => 5432,
139
- 'database' => 'test_slave',
140
- 'host' => 'localhost'
141
- }
142
- end
143
- Slavery.spec_key = 'test_slave_url'
144
- expect(Slavery::ConnectionHolder).to receive(:establish_connection).with(expected)
145
- Slavery::ConnectionHolder.activate
146
- end
147
- end
148
94
  end
@@ -6,25 +6,48 @@ ENV['RACK_ENV'] = 'test'
6
6
  require 'slavery'
7
7
 
8
8
  ActiveRecord::Base.configurations = {
9
- 'test' => { adapter: 'sqlite3', database: 'test_db' },
10
- 'test_slave' => { adapter: 'sqlite3', database: 'test_slave_db' },
11
- 'test_slave_url' => "postgres://root:@localhost:5432/test_slave"
9
+ 'test' => { 'adapter' => 'sqlite3', 'database' => 'test_db' },
10
+ 'test_slave' => { 'adapter' => 'sqlite3', 'database' => 'test_slave_db' },
11
+ 'test_slave_url' => 'postgres://root:@localhost:5432/test_slave'
12
12
  }
13
13
 
14
14
  # Prepare databases
15
15
  class User < ActiveRecord::Base
16
+ has_many :items
16
17
  end
17
18
 
18
- # Create two records on master
19
- ActiveRecord::Base.establish_connection(:test)
20
- ActiveRecord::Base.connection.create_table :users, force: true
21
- User.create
22
- User.create
19
+ class Item < ActiveRecord::Base
20
+ belongs_to :user
21
+ end
22
+
23
+ class Seeder
24
+ def run
25
+ # Populate on master
26
+ connect(:test)
27
+ create_tables
28
+ User.create
29
+ User.create
30
+ User.first.items.create
31
+
32
+ # Populate on slave, emulating replication lag
33
+ connect(:test_slave)
34
+ create_tables
35
+ User.create
23
36
 
24
- # Create one record on slave, emulating replication lag
25
- ActiveRecord::Base.establish_connection(:test_slave)
26
- ActiveRecord::Base.connection.create_table :users, force: true
27
- User.create
37
+ # Reconnect to master
38
+ connect(:test)
39
+ end
40
+
41
+ def create_tables
42
+ ActiveRecord::Base.connection.create_table :users, force: true
43
+ ActiveRecord::Base.connection.create_table :items, force: true do |t|
44
+ t.references :user
45
+ end
46
+ end
47
+
48
+ def connect(env)
49
+ ActiveRecord::Base.establish_connection(env)
50
+ end
51
+ end
28
52
 
29
- # Reconnect to master
30
- ActiveRecord::Base.establish_connection(:test)
53
+ Seeder.new.run
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slavery
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenn Ejima
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-15 00:00:00.000000000 Z
11
+ date: 2017-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -83,6 +83,7 @@ files:
83
83
  - lib/slavery/version.rb
84
84
  - slavery.gemspec
85
85
  - spec/active_record/log_subscriber_spec.rb
86
+ - spec/configuration_spec.rb
86
87
  - spec/slavery_spec.rb
87
88
  - spec/spec_helper.rb
88
89
  homepage: https://github.com/kenn/slavery
@@ -104,11 +105,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
105
  version: '0'
105
106
  requirements: []
106
107
  rubyforge_project:
107
- rubygems_version: 2.5.2
108
+ rubygems_version: 2.6.10
108
109
  signing_key:
109
110
  specification_version: 4
110
111
  summary: Simple, conservative slave reads for ActiveRecord
111
112
  test_files:
112
113
  - spec/active_record/log_subscriber_spec.rb
114
+ - spec/configuration_spec.rb
113
115
  - spec/slavery_spec.rb
114
116
  - spec/spec_helper.rb