switch_point 0.2.3 → 0.3.0

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: 7214878a8ac1b215808ee7fb386f02643ca94961
4
- data.tar.gz: 05cad4a43106ab868ed8bcc47be9ed881a202f7e
3
+ metadata.gz: 4b8ceb04a21d6850779c5fcc61d2b0552bec494f
4
+ data.tar.gz: 0d6cc9ce87e7f320b1b7e14ff7dd3be22578dbde
5
5
  SHA512:
6
- metadata.gz: 6344f088708f67f8bb5bf8d55ed908356469cffda84c7ae65e96e82fa72394f002c26857e576410ee6c3c72b9bfc5e5700e72d07a01e6eab6191a87cd60d1e98
7
- data.tar.gz: 0cebcc98ac866bddc15bd8bc5b1a85669cf09aaadbadeaca24c0fa0b531a4d9e65986ac4dca65f40e90911f319c7e704b51ffc17ba5a28c4755ab2dac248482c
6
+ metadata.gz: cfff954c906a2c517ea9a9fb70780bf3504d076ad25db2db6f37dcbd6eadf34017b5649465a6addc8cdbf477abb79559a8c680385f024a7b5d70a179734bf094
7
+ data.tar.gz: 17a845a358c5ce19a13d8b42d0bef169ffb6c756efc36cc19176bdc4780776e5071982bacac0eb82ebe0ebf33ea8e59de96b23827b03bd6d159c3c74215fc254
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.3.0 (2014-06-04)
2
+ - Improve thread safety
3
+ - Raise appropriate error if unknown mode is given to with_connection
4
+
1
5
  ## 0.2.3 (2014-06-02)
2
6
  - Support specifying the same database name within different switch_point
3
7
  - Add Proxy#readonly? and Proxy#writable? predicate
data/README.md CHANGED
@@ -21,9 +21,6 @@ Or install it yourself as:
21
21
 
22
22
  See [spec/models](spec/models.rb).
23
23
 
24
- ## TODO
25
- - Thread safety
26
-
27
24
  ## Contributing
28
25
 
29
26
  1. Fork it ( https://github.com/eagletmt/switch_point/fork )
@@ -2,15 +2,18 @@ module SwitchPoint
2
2
  class Proxy
3
3
  attr_reader :initial_name
4
4
 
5
+ AVAILABLE_MODES = [:readonly, :writable]
6
+ DEFAULT_MODE = :readonly
7
+
5
8
  def initialize(name)
6
9
  @initial_name = name
7
10
  @current_name = name
8
- [:readonly, :writable].each do |mode|
11
+ AVAILABLE_MODES.each do |mode|
9
12
  model = define_model(SwitchPoint.config.model_name(name, mode))
10
13
  model.establish_connection(SwitchPoint.config.database_name(name, mode))
11
14
  memorize_switch_point(name, mode, model.connection)
12
15
  end
13
- @mode = :readonly
16
+ @global_mode = DEFAULT_MODE
14
17
  end
15
18
 
16
19
  def define_model(model_name)
@@ -24,20 +27,41 @@ module SwitchPoint
24
27
  connection.pool.instance_variable_set(:@switch_point, switch_point)
25
28
  end
26
29
 
30
+ def thread_local_mode
31
+ Thread.current[:"switch_point_#{@current_name}_mode"]
32
+ end
33
+
34
+ def thread_local_mode=(mode)
35
+ Thread.current[:"switch_point_#{@current_name}_mode"] = mode
36
+ end
37
+ private :thread_local_mode=
38
+
39
+ def mode
40
+ thread_local_mode || @global_mode
41
+ end
42
+
27
43
  def readonly!
28
- @mode = :readonly
44
+ if thread_local_mode
45
+ self.thread_local_mode = :readonly
46
+ else
47
+ @global_mode = :readonly
48
+ end
29
49
  end
30
50
 
31
51
  def readonly?
32
- @mode == :readonly
52
+ mode == :readonly
33
53
  end
34
54
 
35
55
  def writable!
36
- @mode = :writable
56
+ if thread_local_mode
57
+ self.thread_local_mode = :writable
58
+ else
59
+ @global_mode = :writable
60
+ end
37
61
  end
38
62
 
39
63
  def writable?
40
- @mode == :writable
64
+ mode == :writable
41
65
  end
42
66
 
43
67
  def with_readonly(&block)
@@ -48,12 +72,15 @@ module SwitchPoint
48
72
  with_connection(:writable, &block)
49
73
  end
50
74
 
51
- def with_connection(mode, &block)
52
- saved_mode = @mode
53
- @mode = mode
75
+ def with_connection(new_mode, &block)
76
+ unless AVAILABLE_MODES.include?(new_mode)
77
+ raise ArgumentError.new("Unknown mode: #{new_mode}")
78
+ end
79
+ saved_mode = self.thread_local_mode
80
+ self.thread_local_mode = new_mode
54
81
  block.call
55
82
  ensure
56
- @mode = saved_mode
83
+ self.thread_local_mode = saved_mode
57
84
  end
58
85
 
59
86
  def switch_name(new_name, &block)
@@ -76,7 +103,7 @@ module SwitchPoint
76
103
 
77
104
  def connection
78
105
  ProxyRepository.checkout(@current_name) # Ensure the target proxy is created
79
- Proxy.const_get(SwitchPoint.config.model_name(@current_name, @mode)).connection
106
+ Proxy.const_get(SwitchPoint.config.model_name(@current_name, mode)).connection
80
107
  end
81
108
  end
82
109
  end
@@ -1,3 +1,3 @@
1
1
  module SwitchPoint
2
- VERSION = "0.2.3"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -142,6 +142,15 @@ RSpec.describe SwitchPoint::Model do
142
142
  expect(Note.with_writable { :bypass }).to eq(:bypass)
143
143
  end
144
144
  end
145
+
146
+ it 'affects thread-locally' do
147
+ Book.with_writable do
148
+ expect(Book).to connect_to('main_writable.sqlite3')
149
+ Thread.start do
150
+ expect(Book).to connect_to('main_readonly.sqlite3')
151
+ end.join
152
+ end
153
+ end
145
154
  end
146
155
 
147
156
  describe '.with_readonly' do
@@ -163,6 +172,12 @@ RSpec.describe SwitchPoint::Model do
163
172
  end
164
173
  end
165
174
 
175
+ describe '#with_connection' do
176
+ it 'raises error if unknown mode is given' do
177
+ expect { SwitchPoint::ProxyRepository.checkout(:main).with_connection(:typo) }.to raise_error
178
+ end
179
+ end
180
+
166
181
  describe '.switch_name' do
167
182
  after do
168
183
  Book.switch_point_proxy.reset_name!
@@ -11,5 +11,25 @@ RSpec.describe SwitchPoint do
11
11
  expect(Book).to connect_to('main_writable.sqlite3')
12
12
  expect(Publisher).to connect_to('main_writable.sqlite3')
13
13
  end
14
+
15
+ it 'affects thread-globally' do
16
+ SwitchPoint.writable!(:main)
17
+ Thread.start do
18
+ expect(Book).to connect_to('main_writable.sqlite3')
19
+ end.join
20
+ end
21
+
22
+ context 'within with block' do
23
+ it 'changes the current mode' do
24
+ Book.with_writable do
25
+ SwitchPoint.readonly!(:main)
26
+ expect(Book).to connect_to('main_readonly.sqlite3')
27
+ end
28
+ expect(Book).to connect_to('main_readonly.sqlite3')
29
+ Book.with_writable do
30
+ expect(Book).to connect_to('main_writable.sqlite3')
31
+ end
32
+ end
33
+ end
14
34
  end
15
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: switch_point
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kohei Suzuki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-02 00:00:00.000000000 Z
11
+ date: 2014-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal