Skip to content

RUBY-949 Initialize topologies to Unknown and discover standalones #641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/mongo/cluster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def initialize(seeds, options = {})
@topology = Topology.initial(seeds, options)
@update_lock = Mutex.new

subscribe_to(Event::STANDALONE_DISCOVERED, Event::StandaloneDiscovered.new(self))
subscribe_to(Event::DESCRIPTION_CHANGED, Event::DescriptionChanged.new(self))
subscribe_to(Event::PRIMARY_ELECTED, Event::PrimaryElected.new(self))

Expand Down Expand Up @@ -136,6 +137,19 @@ def elect_primary!(description)
@topology = topology.elect_primary(description, servers_list)
end

# Notify the cluster that a standalone server was discovered so that the
# topology can be updated accordingly.
#
# @example Notify the cluster that a standalone server was discovered.
# cluster.standalone_discovered
#
# @return [ Topology ] The cluster topology.
#
# @since 2.0.6
def standalone_discovered
@topology = topology.standalone_discovered
end

# Remove the server from the cluster for the provided address, if it
# exists.
#
Expand Down
7 changes: 3 additions & 4 deletions lib/mongo/cluster/topology.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ module Topology
# @since 2.0.0
def initial(seeds, options)
if options.has_key?(:connect)
return OPTIONS.fetch(options[:connect]).new(options, seeds)
end
if options.has_key?(:replica_set)
OPTIONS.fetch(options[:connect]).new(options, seeds)
elsif options.has_key?(:replica_set)
ReplicaSet.new(options, seeds)
else
seeds.size > 1 ? Unknown.new(options, seeds) : Single.new(options, seeds)
Unknown.new(options, seeds)
end
end
end
Expand Down
10 changes: 10 additions & 0 deletions lib/mongo/cluster/topology/replica_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,16 @@ def single?; false; end
# @since 2.0.0
def unknown?; false; end

# Notify the topology that a standalone was discovered.
#
# @example Notify the topology that a standalone was discovered.
# topology.standalone_discovered
#
# @return [ Topology::ReplicaSet ] Always returns self.
#
# @since 2.0.6
def standalone_discovered; self; end

private

def has_primary?(servers)
Expand Down
10 changes: 10 additions & 0 deletions lib/mongo/cluster/topology/sharded.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ def single?; false; end
# @since 2.0.0
def unknown?; false; end

# Notify the topology that a standalone was discovered.
#
# @example Notify the topology that a standalone was discovered.
# topology.standalone_discovered
#
# @return [ Topology::Sharded ] Always returns self.
#
# @since 2.0.6
def standalone_discovered; self; end

private

def remove_self?(description, server)
Expand Down
10 changes: 10 additions & 0 deletions lib/mongo/cluster/topology/single.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ def single?; true; end
#
# @since 2.0.0
def unknown?; false; end

# Notify the topology that a standalone was discovered.
#
# @example Notify the topology that a standalone was discovered.
# topology.standalone_discovered
#
# @return [ Topology::Single ] Always returns self.
#
# @since 2.0.6
def standalone_discovered; self; end
end
end
end
Expand Down
18 changes: 18 additions & 0 deletions lib/mongo/cluster/topology/unknown.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def elect_primary(description, servers)
# @since 2.0.0
def initialize(options, seeds = [])
@options = options
@seeds = seeds
end

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

# Notify the topology that a standalone was discovered.
#
# @example Notify the topology that a standalone was discovered.
# topology.standalone_discovered
#
# @return [ Topology::Unknown, Topology::Single ] Either self or a
# new Single topology.
#
# @since 2.0.6
def standalone_discovered
if @seeds.size == 1
Single.new(options, @seeds)
else
self
end
end

private

def initialize_replica_set(description, servers)
Expand Down
6 changes: 6 additions & 0 deletions lib/mongo/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@
require 'mongo/event/subscriber'
require 'mongo/event/primary_elected'
require 'mongo/event/description_changed'
require 'mongo/event/standalone_discovered'

module Mongo
module Event

# When a standalone is discovered.
#
# @since 2.0.6
STANDALONE_DISCOVERED = 'standalone_discovered'.freeze

# When a server is elected primary.
#
# @since 2.0.0
Expand Down
53 changes: 53 additions & 0 deletions lib/mongo/event/standalone_discovered.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright (C) 2015 MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

module Mongo
module Event

# This handles when a standalone is discovered.
#
# @since 2.0.6
class StandaloneDiscovered

# @return [ Mongo::Cluster ] cluster The event publisher.
attr_reader :cluster

# Initialize the new standalone discovered event handler.
#
# @example Create the new handler.
# StandaloneDiscovered.new(cluster)
#
# @param [ Mongo::Cluster ] cluster The cluster to publish from.
#
# @since 2.0.6
def initialize(cluster)
@cluster = cluster
end

# This event tells the cluster to notify its topology that a standalone
# was discovered.
#
# @example Handle the event.
# standalone_discovered.handle(description)
#
# @param [ Server::Description ] description The description of the
# server.
#
# @since 2.0.6
def handle(description)
cluster.standalone_discovered
end
end
end
end
2 changes: 2 additions & 0 deletions lib/mongo/server/description/inspector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

require 'mongo/server/description/inspector/primary_elected'
require 'mongo/server/description/inspector/description_changed'
require 'mongo/server/description/inspector/standalone_discovered'

module Mongo
class Server
Expand All @@ -31,6 +32,7 @@ class Inspector
#
# @since 2.0.0
INSPECTORS = [
Inspector::StandaloneDiscovered,
Inspector::DescriptionChanged,
Inspector::PrimaryElected
].freeze
Expand Down
56 changes: 56 additions & 0 deletions lib/mongo/server/description/inspector/standalone_discovered.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright (C) 2015 MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

module Mongo
class Server
class Description
class Inspector

# Handles notifying the cluster that a standalone was discovered.
#
# @since 2.0.6
class StandaloneDiscovered
include Event::Publisher

# Instantiate the standalone discovered inspection.
#
# @example Instantiate the inspection.
# StandaloneDiscovered.new(listeners)
#
# @param [ Event::Listeners ] event_listeners The event listeners.
#
# @since 2.0.6
def initialize(event_listeners)
@event_listeners = event_listeners
end

# Run the standalone discovered inspection.
#
# @example Run the inspection.
# StandaloneDiscovered.run(description, {})
#
# @param [ Description ] description The server description.
# @param [ Description ] updated The updated description.
#
# @since 2.0.6
def run(description, updated)
if !description.standalone? && updated.standalone?
publish(Event::STANDALONE_DISCOVERED, updated)
end
end
end
end
end
end
end
12 changes: 6 additions & 6 deletions spec/mongo/cluster/topology_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,26 @@
described_class.initial([], {})
end

it 'returns a single topology' do
expect(topology).to be_a(Mongo::Cluster::Topology::Single)
it 'returns an unknown topology' do
expect(topology).to be_a(Mongo::Cluster::Topology::Unknown)
end
end

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

let(:topology) do
described_class.initial(ADDRESSES, {})
described_class.initial(ADDRESSES, TEST_OPTIONS)
end

it 'returns a single topology' do
expect(topology).to be_a(Mongo::Cluster::Topology::Single)
it 'returns a sharded topology' do
expect(topology).to be_a(Mongo::Cluster::Topology::Sharded)
end
end

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

let(:topology) do
described_class.initial(ADDRESSES, {})
described_class.initial(ADDRESSES, TEST_OPTIONS)
end

it 'returns a single topology' do
Expand Down
2 changes: 1 addition & 1 deletion spec/mongo/server_discovery_and_monitoring_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def family(host)
# @since 2.0.0
class Mongo::Server

# The contructor keeps the same API, but does not instantiate a
# The constructor keeps the same API, but does not instantiate a
# monitor and run it.
def initialize(address, cluster, event_listeners, options = {})
@address = address
Expand Down
33 changes: 33 additions & 0 deletions spec/support/sdam/sharded/single_mongos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
description: "Single mongos"

uri: "mongodb://a"

phases: [

{
responses: [

["a:27017", {

ok: 1,
ismaster: true,
msg: "isdbgrid"
}]
],

outcome: {

servers: {

"a:27017": {

type: "Mongos",
setName:
}
},

topologyType: "Sharded",
setName:
}
}
]