Skip to content

Commit bbc25d1

Browse files
committed
SPEC-222: Replica set check uses server selector
1 parent 5aba3ee commit bbc25d1

File tree

10 files changed

+215
-56
lines changed

10 files changed

+215
-56
lines changed

lib/mongo/cluster/topology/replica_set.rb

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,30 +87,32 @@ def elect_primary(description, servers)
8787
# provided candidates and read preference.
8888
#
8989
# @example Is a readable server present?
90-
# topology.has_readable_server?(servers, read_preference)
90+
# topology.has_readable_server?(cluster, server_selector)
9191
#
92-
# @param [ Array<Server> ] servers The server candidates.
93-
# @param [ ServerSelector, Symbol ] read_preference The read
94-
# preference.
92+
# @param [ Cluster ] cluster The cluster.
93+
# @param [ ServerSelector, Symbol ] server_selector The server
94+
# selector.
9595
#
9696
# @return [ true, false ] If a readable server is present.
9797
#
9898
# @since 2.3.0
99-
def has_readable_server?(servers, read_preference); false; end
99+
def has_readable_server?(cluster, server_selector)
100+
server_selector.candidates(cluster).any?
101+
end
100102

101103
# Determine if the topology would select a writable server for the
102104
# provided candidates.
103105
#
104106
# @example Is a writable server present?
105107
# topology.has_writable_server?(servers)
106108
#
107-
# @param [ Array<Server> ] servers The server candidates.
109+
# @param [ Cluster ] cluster The cluster.
108110
#
109111
# @return [ true, false ] If a writable server is present.
110112
#
111113
# @since 2.3.0
112-
def has_writable_server?(servers)
113-
servers.any?{ |server| server.primary? }
114+
def has_writable_server?(cluster)
115+
cluster.servers.any?{ |server| server.primary? }
114116
end
115117

116118
# Initialize the topology with the options.

lib/mongo/cluster/topology/sharded.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,29 +62,29 @@ def elect_primary(description, servers); self; end
6262
# provided candidates and read preference.
6363
#
6464
# @example Is a readable server present?
65-
# topology.has_readable_server?(servers, read_preference)
65+
# topology.has_readable_server?(cluster, server_selector)
6666
#
67-
# @param [ Array<Server> ] servers The server candidates.
68-
# @param [ ServerSelector, Symbol ] read_preference The read
69-
# preference.
67+
# @param [ Cluster ] cluster The cluster.
68+
# @param [ ServerSelector, Symbol ] server_selector The server
69+
# selector.
7070
#
7171
# @return [ true, false ] If a readable server is present.
7272
#
7373
# @since 2.3.0
74-
def has_readable_server?(servers, read_preference); true; end
74+
def has_readable_server?(cluster, server_selector); true; end
7575

7676
# Determine if the topology would select a writable server for the
7777
# provided candidates.
7878
#
7979
# @example Is a writable server present?
8080
# topology.has_writable_server?(servers)
8181
#
82-
# @param [ Array<Server> ] servers The server candidates.
82+
# @param [ Cluster ] cluster The cluster.
8383
#
8484
# @return [ true, false ] If a writable server is present.
8585
#
8686
# @since 2.3.0
87-
def has_writable_server?(servers); true; end
87+
def has_writable_server?(cluster); true; end
8888

8989
# Initialize the topology with the options.
9090
#

lib/mongo/cluster/topology/single.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,30 +65,30 @@ def elect_primary(description, servers); self; end
6565
# provided candidates and read preference.
6666
#
6767
# @example Is a readable server present?
68-
# topology.has_readable_server?(servers, read_preference)
68+
# topology.has_readable_server?(cluster, server_selector)
6969
#
70-
# @param [ Array<Server> ] servers The server candidates.
71-
# @param [ ServerSelector, Symbol ] read_preference The read
72-
# preference.
70+
# @param [ Cluster ] cluster The cluster.
71+
# @param [ ServerSelector, Symbol ] server_selector The server
72+
# selector.
7373
#
7474
# @return [ true, false ] If a readable server is present.
7575
#
7676
# @since 2.3.0
77-
def has_readable_server?(servers, read_preference); true; end
77+
def has_readable_server?(cluster, server_selector); true; end
7878

7979
# Determine if the topology would select a writable server for the
8080
# provided candidates.
8181
#
8282
# @example Is a writable server present?
8383
# topology.has_writable_server?(servers)
8484
#
85-
# @param [ Array<Server> ] servers The server candidates.
85+
# @param [ Cluster ] cluster The cluster.
8686
#
8787
# @return [ true, false ] If a writable server is present.
8888
#
8989
# @since 2.3.0
90-
def has_writable_server?(servers)
91-
servers.any?{ |server| server.primary? }
90+
def has_writable_server?(cluster)
91+
cluster.servers.any?{ |server| server.primary? }
9292
end
9393

9494
# Initialize the topology with the options.

lib/mongo/cluster/topology/unknown.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,29 +71,29 @@ def elect_primary(description, servers)
7171
# provided candidates and read preference.
7272
#
7373
# @example Is a readable server present?
74-
# topology.has_readable_server?(servers, read_preference)
74+
# topology.has_readable_server?(cluster, server_selector)
7575
#
76-
# @param [ Array<Server> ] servers The server candidates.
77-
# @param [ ServerSelector, Symbol ] read_preference The read
78-
# preference.
76+
# @param [ Cluster ] cluster The cluster.
77+
# @param [ ServerSelector, Symbol ] server_selector The server
78+
# selector.
7979
#
8080
# @return [ true, false ] If a readable server is present.
8181
#
8282
# @since 2.3.0
83-
def has_readable_server?(servers, read_preference); false; end
83+
def has_readable_server?(cluster, server_selector); false; end
8484

8585
# Determine if the topology would select a writable server for the
8686
# provided candidates.
8787
#
8888
# @example Is a writable server present?
8989
# topology.has_writable_server?(servers)
9090
#
91-
# @param [ Array<Server> ] servers The server candidates.
91+
# @param [ Cluster ] cluster The cluster.
9292
#
9393
# @return [ true, false ] If a writable server is present.
9494
#
9595
# @since 2.3.0
96-
def has_writable_server?(servers); false; end
96+
def has_writable_server?(cluster); false; end
9797

9898
# Initialize the topology with the options.
9999
#

lib/mongo/server_selector.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ module ServerSelector
4848
#
4949
# @since 2.0.0
5050
PREFERENCES = {
51-
nearest: Nearest,
52-
primary: Primary,
53-
primary_preferred: PrimaryPreferred,
54-
secondary: Secondary,
55-
secondary_preferred: SecondaryPreferred
51+
nearest: Nearest,
52+
primary: Primary,
53+
primary_preferred: PrimaryPreferred,
54+
secondary: Secondary,
55+
secondary_preferred: SecondaryPreferred
5656
}.freeze
5757

5858
# Create a server selector object.

lib/mongo/server_selector/selectable.rb

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ def ==(other)
4040
name == other.name && tag_sets == other.tag_sets
4141
end
4242

43+
# Get the potential candidates to selecto from the cluster.
44+
#
45+
# @example Get the server candidates.
46+
# selectable.candidates(cluster)
47+
#
48+
# @param [ Cluster ] cluster The cluster.
49+
#
50+
# @return [ Array<Server> ] The candidate servers.
51+
#
52+
# @since 2.3.0
53+
def candidates(cluster)
54+
if cluster.single?
55+
cluster.servers
56+
elsif cluster.sharded?
57+
near_servers(cluster.servers)
58+
else
59+
select(cluster.servers)
60+
end
61+
end
62+
4363
# Initialize the server selector.
4464
#
4565
# @example Initialize the selector.
@@ -136,16 +156,6 @@ def local_threshold
136156

137157
private
138158

139-
def candidates(cluster)
140-
if cluster.single?
141-
cluster.servers
142-
elsif cluster.sharded?
143-
near_servers(cluster.servers)
144-
else
145-
select(cluster.servers)
146-
end
147-
end
148-
149159
# Select the primary from a list of provided candidates.
150160
#
151161
# @param [ Array ] candidates List of candidate servers to select the

spec/mongo/address/unix_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
end
2525
end
2626

27-
describe '#socket' do
27+
pending '#socket' do
2828

2929
let(:address) do
3030
'/tmp/mongodb-27017.sock'

spec/mongo/cluster/topology/replica_set_spec.rb

Lines changed: 144 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,140 @@
117117
described_class.new({}, monitoring, [])
118118
end
119119

120-
it 'test read preference'
120+
let(:cluster) do
121+
double('cluster', servers: servers, single?: false, sharded?: false)
122+
end
123+
124+
context 'when the read preference is primary' do
125+
126+
let(:selector) do
127+
Mongo::ServerSelector.get(:mode => :primary)
128+
end
129+
130+
context 'when a primary exists' do
131+
132+
let(:servers) do
133+
[ double('server', primary?: true) ]
134+
end
135+
136+
it 'returns true' do
137+
expect(topology).to have_readable_server(cluster, selector)
138+
end
139+
end
140+
141+
context 'when a primary does not exist' do
142+
143+
let(:servers) do
144+
[ double('server', primary?: false) ]
145+
end
146+
147+
it 'returns false' do
148+
expect(topology).to_not have_readable_server(cluster, selector)
149+
end
150+
end
151+
end
152+
153+
context 'when the read preference is primary preferred' do
154+
155+
let(:selector) do
156+
Mongo::ServerSelector.get(:mode => :primary_preferred)
157+
end
158+
159+
context 'when a primary exists' do
160+
161+
let(:servers) do
162+
[ double('server', primary?: true) ]
163+
end
164+
165+
it 'returns true' do
166+
expect(topology).to have_readable_server(cluster, selector)
167+
end
168+
end
169+
170+
context 'when a primary does not exist' do
171+
172+
let(:servers) do
173+
[ double('server', primary?: false, secondary?: true, average_round_trip_time: 0.01) ]
174+
end
175+
176+
it 'returns true' do
177+
expect(topology).to have_readable_server(cluster, selector)
178+
end
179+
end
180+
end
181+
182+
context 'when the read preference is secondary' do
183+
184+
let(:selector) do
185+
Mongo::ServerSelector.get(:mode => :secondary)
186+
end
187+
188+
context 'when a secondary exists' do
189+
190+
let(:servers) do
191+
[ double('server', secondary?: true, average_round_trip_time: 0.01) ]
192+
end
193+
194+
it 'returns true' do
195+
expect(topology).to have_readable_server(cluster, selector)
196+
end
197+
end
198+
199+
context 'when a secondary does not exist' do
200+
201+
let(:servers) do
202+
[ double('server', secondary?: false) ]
203+
end
204+
205+
it 'returns false' do
206+
expect(topology).to_not have_readable_server(cluster, selector)
207+
end
208+
end
209+
end
210+
211+
context 'when the read preference is secondary preferred' do
212+
213+
let(:selector) do
214+
Mongo::ServerSelector.get(:mode => :secondary_preferred)
215+
end
216+
217+
context 'when a secondary exists' do
218+
219+
let(:servers) do
220+
[ double('server', primary?: false, secondary?: true, average_round_trip_time: 0.01) ]
221+
end
222+
223+
it 'returns true' do
224+
expect(topology).to have_readable_server(cluster, selector)
225+
end
226+
end
227+
228+
context 'when a secondary does not exist' do
229+
230+
let(:servers) do
231+
[ double('server', secondary?: false, primary?: true) ]
232+
end
233+
234+
it 'returns true' do
235+
expect(topology).to have_readable_server(cluster, selector)
236+
end
237+
end
238+
end
239+
240+
context 'when the read preference is nearest' do
241+
242+
let(:selector) do
243+
Mongo::ServerSelector.get(:mode => :nearest)
244+
end
245+
246+
let(:servers) do
247+
[ double('server', primary?: false, secondary?: true, average_round_trip_time: 0.01) ]
248+
end
249+
250+
it 'returns true' do
251+
expect(topology).to have_readable_server(cluster, selector)
252+
end
253+
end
121254
end
122255

123256
describe '#has_writable_servers?' do
@@ -136,8 +269,12 @@
136269
double('server', :primary? => false)
137270
end
138271

272+
let(:cluster) do
273+
double('cluster', servers: [ primary, secondary ])
274+
end
275+
139276
it 'returns true' do
140-
expect(topology).to have_writable_server([ primary, secondary ])
277+
expect(topology).to have_writable_server(cluster)
141278
end
142279
end
143280

@@ -147,8 +284,12 @@
147284
double('server', :primary? => false)
148285
end
149286

287+
let(:cluster) do
288+
double('cluster', servers: [ server ])
289+
end
290+
150291
it 'returns false' do
151-
expect(topology).to_not have_writable_server([ server ])
292+
expect(topology).to_not have_writable_server(cluster)
152293
end
153294
end
154295
end

0 commit comments

Comments
 (0)