Skip to content

Commit 4a65e04

Browse files
committed
Merge pull request #641 from estolfo/RUBY-949-single-mongos
RUBY-949 Initialize topologies to Unknown and discover standalones
2 parents 3932525 + fa1f4a1 commit 4a65e04

File tree

13 files changed

+222
-11
lines changed

13 files changed

+222
-11
lines changed

lib/mongo/cluster.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def initialize(seeds, options = {})
9191
@topology = Topology.initial(seeds, options)
9292
@update_lock = Mutex.new
9393

94+
subscribe_to(Event::STANDALONE_DISCOVERED, Event::StandaloneDiscovered.new(self))
9495
subscribe_to(Event::DESCRIPTION_CHANGED, Event::DescriptionChanged.new(self))
9596
subscribe_to(Event::PRIMARY_ELECTED, Event::PrimaryElected.new(self))
9697

@@ -136,6 +137,19 @@ def elect_primary!(description)
136137
@topology = topology.elect_primary(description, servers_list)
137138
end
138139

140+
# Notify the cluster that a standalone server was discovered so that the
141+
# topology can be updated accordingly.
142+
#
143+
# @example Notify the cluster that a standalone server was discovered.
144+
# cluster.standalone_discovered
145+
#
146+
# @return [ Topology ] The cluster topology.
147+
#
148+
# @since 2.0.6
149+
def standalone_discovered
150+
@topology = topology.standalone_discovered
151+
end
152+
139153
# Remove the server from the cluster for the provided address, if it
140154
# exists.
141155
#

lib/mongo/cluster/topology.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ module Topology
4848
# @since 2.0.0
4949
def initial(seeds, options)
5050
if options.has_key?(:connect)
51-
return OPTIONS.fetch(options[:connect]).new(options, seeds)
52-
end
53-
if options.has_key?(:replica_set)
51+
OPTIONS.fetch(options[:connect]).new(options, seeds)
52+
elsif options.has_key?(:replica_set)
5453
ReplicaSet.new(options, seeds)
5554
else
56-
seeds.size > 1 ? Unknown.new(options, seeds) : Single.new(options, seeds)
55+
Unknown.new(options, seeds)
5756
end
5857
end
5958
end

lib/mongo/cluster/topology/replica_set.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,16 @@ def single?; false; end
203203
# @since 2.0.0
204204
def unknown?; false; end
205205

206+
# Notify the topology that a standalone was discovered.
207+
#
208+
# @example Notify the topology that a standalone was discovered.
209+
# topology.standalone_discovered
210+
#
211+
# @return [ Topology::ReplicaSet ] Always returns self.
212+
#
213+
# @since 2.0.6
214+
def standalone_discovered; self; end
215+
206216
private
207217

208218
def has_primary?(servers)

lib/mongo/cluster/topology/sharded.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ def single?; false; end
171171
# @since 2.0.0
172172
def unknown?; false; end
173173

174+
# Notify the topology that a standalone was discovered.
175+
#
176+
# @example Notify the topology that a standalone was discovered.
177+
# topology.standalone_discovered
178+
#
179+
# @return [ Topology::Sharded ] Always returns self.
180+
#
181+
# @since 2.0.6
182+
def standalone_discovered; self; end
183+
174184
private
175185

176186
def remove_self?(description, server)

lib/mongo/cluster/topology/single.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ def single?; true; end
171171
#
172172
# @since 2.0.0
173173
def unknown?; false; end
174+
175+
# Notify the topology that a standalone was discovered.
176+
#
177+
# @example Notify the topology that a standalone was discovered.
178+
# topology.standalone_discovered
179+
#
180+
# @return [ Topology::Single ] Always returns self.
181+
#
182+
# @since 2.0.6
183+
def standalone_discovered; self; end
174184
end
175185
end
176186
end

lib/mongo/cluster/topology/unknown.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def elect_primary(description, servers)
7272
# @since 2.0.0
7373
def initialize(options, seeds = [])
7474
@options = options
75+
@seeds = seeds
7576
end
7677

7778
# An unknown topology is not a replica set.
@@ -183,6 +184,23 @@ def remove_server?(description, server)
183184
description.standalone? && description.is_server?(server)
184185
end
185186

187+
# Notify the topology that a standalone was discovered.
188+
#
189+
# @example Notify the topology that a standalone was discovered.
190+
# topology.standalone_discovered
191+
#
192+
# @return [ Topology::Unknown, Topology::Single ] Either self or a
193+
# new Single topology.
194+
#
195+
# @since 2.0.6
196+
def standalone_discovered
197+
if @seeds.size == 1
198+
Single.new(options, @seeds)
199+
else
200+
self
201+
end
202+
end
203+
186204
private
187205

188206
def initialize_replica_set(description, servers)

lib/mongo/event.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@
1717
require 'mongo/event/subscriber'
1818
require 'mongo/event/primary_elected'
1919
require 'mongo/event/description_changed'
20+
require 'mongo/event/standalone_discovered'
2021

2122
module Mongo
2223
module Event
2324

25+
# When a standalone is discovered.
26+
#
27+
# @since 2.0.6
28+
STANDALONE_DISCOVERED = 'standalone_discovered'.freeze
29+
2430
# When a server is elected primary.
2531
#
2632
# @since 2.0.0
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright (C) 2015 MongoDB, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module Mongo
16+
module Event
17+
18+
# This handles when a standalone is discovered.
19+
#
20+
# @since 2.0.6
21+
class StandaloneDiscovered
22+
23+
# @return [ Mongo::Cluster ] cluster The event publisher.
24+
attr_reader :cluster
25+
26+
# Initialize the new standalone discovered event handler.
27+
#
28+
# @example Create the new handler.
29+
# StandaloneDiscovered.new(cluster)
30+
#
31+
# @param [ Mongo::Cluster ] cluster The cluster to publish from.
32+
#
33+
# @since 2.0.6
34+
def initialize(cluster)
35+
@cluster = cluster
36+
end
37+
38+
# This event tells the cluster to notify its topology that a standalone
39+
# was discovered.
40+
#
41+
# @example Handle the event.
42+
# standalone_discovered.handle(description)
43+
#
44+
# @param [ Server::Description ] description The description of the
45+
# server.
46+
#
47+
# @since 2.0.6
48+
def handle(description)
49+
cluster.standalone_discovered
50+
end
51+
end
52+
end
53+
end

lib/mongo/server/description/inspector.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
require 'mongo/server/description/inspector/primary_elected'
1616
require 'mongo/server/description/inspector/description_changed'
17+
require 'mongo/server/description/inspector/standalone_discovered'
1718

1819
module Mongo
1920
class Server
@@ -31,6 +32,7 @@ class Inspector
3132
#
3233
# @since 2.0.0
3334
INSPECTORS = [
35+
Inspector::StandaloneDiscovered,
3436
Inspector::DescriptionChanged,
3537
Inspector::PrimaryElected
3638
].freeze
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright (C) 2015 MongoDB, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module Mongo
16+
class Server
17+
class Description
18+
class Inspector
19+
20+
# Handles notifying the cluster that a standalone was discovered.
21+
#
22+
# @since 2.0.6
23+
class StandaloneDiscovered
24+
include Event::Publisher
25+
26+
# Instantiate the standalone discovered inspection.
27+
#
28+
# @example Instantiate the inspection.
29+
# StandaloneDiscovered.new(listeners)
30+
#
31+
# @param [ Event::Listeners ] event_listeners The event listeners.
32+
#
33+
# @since 2.0.6
34+
def initialize(event_listeners)
35+
@event_listeners = event_listeners
36+
end
37+
38+
# Run the standalone discovered inspection.
39+
#
40+
# @example Run the inspection.
41+
# StandaloneDiscovered.run(description, {})
42+
#
43+
# @param [ Description ] description The server description.
44+
# @param [ Description ] updated The updated description.
45+
#
46+
# @since 2.0.6
47+
def run(description, updated)
48+
if !description.standalone? && updated.standalone?
49+
publish(Event::STANDALONE_DISCOVERED, updated)
50+
end
51+
end
52+
end
53+
end
54+
end
55+
end
56+
end

spec/mongo/cluster/topology_spec.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,26 @@
6060
described_class.initial([], {})
6161
end
6262

63-
it 'returns a single topology' do
64-
expect(topology).to be_a(Mongo::Cluster::Topology::Single)
63+
it 'returns an unknown topology' do
64+
expect(topology).to be_a(Mongo::Cluster::Topology::Unknown)
6565
end
6666
end
6767

6868
context 'when provided a single mongos', if: single_mongos? do
6969

7070
let(:topology) do
71-
described_class.initial(ADDRESSES, {})
71+
described_class.initial(ADDRESSES, TEST_OPTIONS)
7272
end
7373

74-
it 'returns a single topology' do
75-
expect(topology).to be_a(Mongo::Cluster::Topology::Single)
74+
it 'returns a sharded topology' do
75+
expect(topology).to be_a(Mongo::Cluster::Topology::Sharded)
7676
end
7777
end
7878

7979
context 'when provided a single replica set member', if: single_rs_member? do
8080

8181
let(:topology) do
82-
described_class.initial(ADDRESSES, {})
82+
described_class.initial(ADDRESSES, TEST_OPTIONS)
8383
end
8484

8585
it 'returns a single topology' do

spec/mongo/server_discovery_and_monitoring_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def family(host)
3232
# @since 2.0.0
3333
class Mongo::Server
3434

35-
# The contructor keeps the same API, but does not instantiate a
35+
# The constructor keeps the same API, but does not instantiate a
3636
# monitor and run it.
3737
def initialize(address, cluster, event_listeners, options = {})
3838
@address = address
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
description: "Single mongos"
2+
3+
uri: "mongodb://a"
4+
5+
phases: [
6+
7+
{
8+
responses: [
9+
10+
["a:27017", {
11+
12+
ok: 1,
13+
ismaster: true,
14+
msg: "isdbgrid"
15+
}]
16+
],
17+
18+
outcome: {
19+
20+
servers: {
21+
22+
"a:27017": {
23+
24+
type: "Mongos",
25+
setName:
26+
}
27+
},
28+
29+
topologyType: "Sharded",
30+
setName:
31+
}
32+
}
33+
]

0 commit comments

Comments
 (0)