Skip to content

Commit 24e87cb

Browse files
committed
RUBY-932 Update Server Discovery and Monitoring code and tests
1 parent 9b134b1 commit 24e87cb

24 files changed

+445
-340
lines changed

lib/mongo/cluster.rb

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ def initialize(seeds, options = {})
9595
@topology = Topology.initial(seeds, options)
9696
@slave_ok = @topology.single? unless options[:read]
9797

98-
subscribe_to(Event::SERVER_ADDED, Event::ServerAdded.new(self))
99-
subscribe_to(Event::SERVER_REMOVED, Event::ServerRemoved.new(self))
98+
subscribe_to(Event::DESCRIPTION_CHANGED, Event::DescriptionChanged.new(self))
10099
subscribe_to(Event::PRIMARY_ELECTED, Event::PrimaryElected.new(self))
101100

102101
seeds.each{ |seed| add(seed) }
@@ -141,7 +140,7 @@ def elect_primary!(description)
141140
@topology = topology.elect_primary(description, @servers)
142141
end
143142

144-
# Removed the server from the cluster for the provided address, if it
143+
# Remove the server from the cluster for the provided address, if it
145144
# exists.
146145
#
147146
# @example Remove the server from the cluster.
@@ -186,6 +185,36 @@ def servers
186185
topology.servers(@servers.compact).compact
187186
end
188187

188+
# Add hosts in a description to the cluster.
189+
#
190+
# @example Add hosts in a description to the cluster.
191+
# cluster.add_hosts(description)
192+
#
193+
# @param [ Mongo::Server::Description ] description The description.
194+
#
195+
# @since 2.0.6
196+
def add_hosts(description)
197+
if topology.add_hosts?(description, @servers)
198+
description.servers.each { |s| add(s) }
199+
end
200+
end
201+
202+
# Remove hosts in a description from the cluster.
203+
#
204+
# @example Remove hosts in a description from the cluster.
205+
# cluster.remove_hosts(description)
206+
#
207+
# @param [ Mongo::Server::Description ] description The description.
208+
#
209+
# @since 2.0.6
210+
def remove_hosts(description)
211+
if topology.remove_hosts?(description)
212+
@servers.each do |s|
213+
remove(s.address.to_s) if topology.remove_server?(description, s)
214+
end
215+
end
216+
end
217+
189218
# Create a cluster for the provided client, for use when we don't want the
190219
# client's original cluster instance to be the same.
191220
#

lib/mongo/cluster/topology/replica_set.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,56 @@ def servers(servers)
125125
end
126126
end
127127

128+
# Whether a server description's hosts may be added to the cluster.
129+
#
130+
# @example Check if a description's hosts may be added to the cluster.
131+
# topology.add_hosts?(description, servers)
132+
#
133+
# @param [ Mongo::Server::Description ] description The description.
134+
# @param [ Array<Mongo::Server> ] servers The cluster servers.
135+
#
136+
# @return [ true, false ] Whether a description's hosts may be added.
137+
#
138+
# @since 2.0.6
139+
def add_hosts?(description, servers)
140+
if !has_primary?(servers)
141+
member_of_this_set?(description)
142+
end
143+
end
144+
145+
# Whether a description can be used to remove hosts from the cluster.
146+
#
147+
# @example Check if a description can be used to remove hosts from the cluster.
148+
# topology.remove_hosts?(description)
149+
#
150+
# @param [ Mongo::Server::Description ] description The description.
151+
#
152+
# @return [ true, false ] Whether hosts may be removed from the cluster.
153+
#
154+
# @since 2.0.6
155+
def remove_hosts?(description)
156+
!description.config.empty? &&
157+
(description.primary? ||
158+
description.hosts.empty? ||
159+
!member_of_this_set?(description))
160+
end
161+
162+
# Whether a specific server in the cluster can be removed, given a description.
163+
#
164+
# @example Check if a specific server can be removed from the cluster.
165+
# topology.remove_server?(description, server)
166+
#
167+
# @param [ Mongo::Server::Description ] description The description.
168+
# @param [ Mongo::Serve ] server The server in question.
169+
#
170+
# @return [ true, false ] Whether the server can be removed from the cluster.
171+
#
172+
# @since 2.0.6
173+
def remove_server?(description, server)
174+
remove_self?(description, server) ||
175+
(member_of_this_set?(description) && !description.included?(server))
176+
end
177+
128178
# A replica set topology is not sharded.
129179
#
130180
# @example Is the topology sharded?
@@ -154,6 +204,23 @@ def single?; false; end
154204
#
155205
# @since 2.0.0
156206
def unknown?; false; end
207+
208+
private
209+
210+
def has_primary?(servers)
211+
servers.find { |s| s.primary? }
212+
end
213+
214+
def member_of_this_set?(description)
215+
description.replica_set_member? &&
216+
description.replica_set_name == replica_set_name
217+
end
218+
219+
def remove_self?(description, server)
220+
!member_of_this_set?(description) &&
221+
description.self?(server) &&
222+
!description.ghost?
223+
end
157224
end
158225
end
159226
end

lib/mongo/cluster/topology/sharded.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,50 @@ def servers(servers)
9797
servers.select{ |server| server.mongos? }
9898
end
9999

100+
# Whether a server description's hosts may be added to the cluster.
101+
#
102+
# @example Check if a description's hosts may be added to the cluster.
103+
# topology.add_hosts?(description, servers)
104+
#
105+
# @param [ Mongo::Server::Description ] description The description.
106+
# @param [ Array<Mongo::Server> ] servers The cluster servers.
107+
#
108+
# @return [ false ] A description's hosts are never added to a
109+
# sharded cluster.
110+
#
111+
# @since 2.0.6
112+
def add_hosts?(description, servers); false; end
113+
114+
# Whether a description can be used to remove hosts from the cluster.
115+
#
116+
# @example Check if a description can be used to remove hosts from
117+
# the cluster.
118+
# topology.remove_hosts?(description)
119+
#
120+
# @param [ Mongo::Server::Description ] description The description.
121+
#
122+
# @return [ true ] A description can always be used to remove hosts
123+
# from a sharded cluster.
124+
#
125+
# @since 2.0.6
126+
def remove_hosts?(description); true; end
127+
128+
# Whether a specific server in the cluster can be removed, given a description.
129+
#
130+
# @example Check if a specific server can be removed from the cluster.
131+
# topology.remove_server?(description, server)
132+
#
133+
# @param [ Mongo::Server::Description ] description The description.
134+
# @param [ Mongo::Serve ] server The server in question.
135+
#
136+
# @return [ true, false ] Whether the server can be removed from the cluster.
137+
#
138+
# @since 2.0.6
139+
def remove_server?(description, server)
140+
remove_self?(description, server) ||
141+
!(server.mongos? || server.unknown?)
142+
end
143+
100144
# A sharded topology is sharded.
101145
#
102146
# @example Is the topology sharded?
@@ -126,6 +170,12 @@ def single?; false; end
126170
#
127171
# @since 2.0.0
128172
def unknown?; false; end
173+
174+
private
175+
176+
def remove_self?(description, server)
177+
description.self?(server) && !description.mongos?
178+
end
129179
end
130180
end
131181
end

lib/mongo/cluster/topology/single.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,47 @@ def servers(servers, name = nil)
101101
[ servers.detect { |server| !server.unknown? } ]
102102
end
103103

104+
# Whether a server description's hosts may be added to the cluster.
105+
#
106+
# @example Check if a description's hosts may be added to the cluster.
107+
# topology.add_hosts?(description, servers)
108+
#
109+
# @param [ Mongo::Server::Description ] description The description.
110+
# @param [ Array<Mongo::Server> ] servers The cluster servers.
111+
#
112+
# @return [ false ] A description's hosts are never added to a
113+
# cluster of Single topology.
114+
#
115+
# @since 2.0.6
116+
def add_hosts?(description, servers); false; end
117+
118+
# Whether a description can be used to remove hosts from the cluster.
119+
#
120+
# @example Check if a description can be used to remove hosts from
121+
# the cluster.
122+
# topology.remove_hosts?(description)
123+
#
124+
# @param [ Mongo::Server::Description ] description The description.
125+
#
126+
# @return [ true ] A description can never be used to remove hosts
127+
# from a cluster of Single topology.
128+
#
129+
# @since 2.0.6
130+
def remove_hosts?(description); false; end
131+
132+
# Whether a specific server in the cluster can be removed, given a description.
133+
#
134+
# @example Check if a specific server can be removed from the cluster.
135+
# topology.remove_server?(description, server)
136+
#
137+
# @param [ Mongo::Server::Description ] description The description.
138+
# @param [ Mongo::Serve ] server The server in question.
139+
#
140+
# @return [ false ] A server is never removed from a cluster of Single topology.
141+
#
142+
# @since 2.0.6
143+
def remove_server?(description, server); false; end
144+
104145
# A single topology is not sharded.
105146
#
106147
# @example Is the topology sharded?

lib/mongo/cluster/topology/unknown.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,50 @@ def single?; false; end
139139
# @since 2.0.0
140140
def unknown?; true; end
141141

142+
# Whether a server description's hosts may be added to the cluster.
143+
#
144+
# @example Check if a description's hosts may be added to the cluster.
145+
# topology.add_hosts?(description, servers)
146+
#
147+
# @param [ Mongo::Server::Description ] description The description.
148+
# @param [ Array<Mongo::Server> ] servers The cluster servers.
149+
#
150+
# @return [ true, false ] Whether a description's hosts may be added.
151+
#
152+
# @since 2.0.6
153+
def add_hosts?(description, servers)
154+
!(description.unknown? || description.ghost?)
155+
end
156+
157+
# Whether a description can be used to remove hosts from the cluster.
158+
#
159+
# @example Check if a description can be used to remove hosts from the cluster.
160+
# topology.remove_hosts?(description)
161+
#
162+
# @param [ Mongo::Server::Description ] description The description.
163+
#
164+
# @return [ true, false ] Whether hosts may be removed from the cluster.
165+
#
166+
# @since 2.0.6
167+
def remove_hosts?(description)
168+
description.standalone?
169+
end
170+
171+
# Whether a specific server in the cluster can be removed, given a description.
172+
#
173+
# @example Check if a specific server can be removed from the cluster.
174+
# topology.remove_server?(description, server)
175+
#
176+
# @param [ Mongo::Server::Description ] description The description.
177+
# @param [ Mongo::Serve ] server The server in question.
178+
#
179+
# @return [ true, false ] Whether the server can be removed from the cluster.
180+
#
181+
# @since 2.0.6
182+
def remove_server?(description, server)
183+
description.standalone? && description.self?(server)
184+
end
185+
142186
private
143187

144188
def initialize_replica_set(description, servers)

lib/mongo/event.rb

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
require 'mongo/event/publisher'
1717
require 'mongo/event/subscriber'
1818
require 'mongo/event/primary_elected'
19-
require 'mongo/event/server_added'
20-
require 'mongo/event/server_removed'
19+
require 'mongo/event/description_changed'
2120

2221
module Mongo
2322
module Event
@@ -27,14 +26,9 @@ module Event
2726
# @since 2.0.0
2827
PRIMARY_ELECTED = 'primary_elected'.freeze
2928

30-
# When a server is to be added to a cluster.
31-
#
32-
# @since 2.0.0
33-
SERVER_ADDED = 'server_added'.freeze
34-
3529
# When a server is to be removed from a cluster.
3630
#
37-
# @since 2.0.0
38-
SERVER_REMOVED = 'server_removed'.freeze
31+
# @since 2.0.5
32+
DESCRIPTION_CHANGED = 'description_changed'.freeze
3933
end
4034
end

lib/mongo/event/server_added.rb renamed to lib/mongo/event/description_changed.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
module Mongo
1717
module Event
1818

19-
# This handles host added events for server descriptions.
19+
# This handles a change in description.
2020
#
21-
# @since 2.0.0
22-
class ServerAdded
21+
# @since 2.0.5
22+
class DescriptionChanged
2323

2424
# @return [ Mongo::Cluster ] cluster The event publisher.
2525
attr_reader :cluster
@@ -45,8 +45,9 @@ def initialize(cluster)
4545
# @param [ Address ] address The added host.
4646
#
4747
# @since 2.0.0
48-
def handle(address)
49-
cluster.add(address)
48+
def handle(updated)
49+
cluster.add_hosts(updated)
50+
cluster.remove_hosts(updated)
5051
end
5152
end
5253
end

0 commit comments

Comments
 (0)