Skip to content

Commit

Permalink
Merge pull request #365 from mongodb/description-change-events
Browse files Browse the repository at this point in the history
Add description change events.
  • Loading branch information
durran committed Feb 23, 2014
2 parents 2ce15cb + 4d4de9f commit fcf075f
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 24 deletions.
25 changes: 19 additions & 6 deletions lib/mongo/event.rb
Expand Up @@ -14,18 +14,31 @@


require 'mongo/event/publisher' require 'mongo/event/publisher'
require 'mongo/event/subscriber' require 'mongo/event/subscriber'
require 'mongo/event/host_added'
require 'mongo/event/host_removed'


module Mongo module Mongo


module Event module Event


ARBITER_ADDED = "arbiter_added".freeze # When a server description has a new host added.
ARBITER_REMOVED = "arbiter_removed".freeze #
# @since 3.0.0
HOST_ADDED = "host_added".freeze


SECONDARY_ADDED = "server_added".freeze # When a server description has a host removed.
SECONDARY_REMOVED = "server_removed".freeze #
# @since 3.0.0
HOST_REMOVED = "host_removed".freeze


SERVER_PROMOTED = "server_promoted".freeze # When a server is to be added to a cluster.
SERVER_DEMOTED = "server_demoted".freeze #
# @since 3.0.0
SERVER_ADDED = "server_added".freeze

# When a server is to be removed from a cluster.
#
# @since 3.0.0
SERVER_REMOVED = "server_removed".freeze
end end
end end
44 changes: 44 additions & 0 deletions lib/mongo/event/host_added.rb
@@ -0,0 +1,44 @@
# Copyright (C) 2009-2014 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 host added events for server descriptions.
#
# @since 3.0.0
class HostAdded

# @return [ Mongo::Server ] server The event publisher.
attr_reader :server

# Initialize the new host added event handler.
#
# @example Create the new handler.
# HostAdded.new(server)
#
# @param [ Mongo::Server ] server The server to publish from.
#
# @since 3.0.0
def initialize(server)
@server = server
end

def handle(address)
# @todo: Log the description change here.
server.publish(Event::SERVER_ADDED, address)
end
end
end
end
44 changes: 44 additions & 0 deletions lib/mongo/event/host_removed.rb
@@ -0,0 +1,44 @@
# Copyright (C) 2009-2014 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 host removed events for server descriptions.
#
# @since 3.0.0
class HostRemoved

# @return [ Mongo::Server ] server The event publisher.
attr_reader :server

# Initialize the new host removed event handler.
#
# @example Create the new handler.
# HostRemoved.new(server)
#
# @param [ Mongo::Server ] server The server to publish from.
#
# @since 3.0.0
def initialize(server)
@server = server
end

def handle(address)
# @todo: Log the description change here.
server.publish(Event::SERVER_REMOVED, address)
end
end
end
end
32 changes: 24 additions & 8 deletions lib/mongo/server.rb
Expand Up @@ -24,6 +24,7 @@ module Mongo
# @since 3.0.0 # @since 3.0.0
class Server class Server
include Event::Publisher include Event::Publisher
include Event::Subscriber


# The default time for a server to refresh its status is 5 seconds. # The default time for a server to refresh its status is 5 seconds.
# #
Expand Down Expand Up @@ -52,6 +53,7 @@ def initialize(address, options = {})
@address = Address.new(address) @address = Address.new(address)
@options = options @options = options
@mutex = Mutex.new @mutex = Mutex.new
initialize_description!
@refresh = Refresh.new(self, refresh_interval) @refresh = Refresh.new(self, refresh_interval)
@refresh.run @refresh.run
end end
Expand All @@ -60,15 +62,22 @@ def operable?
true true
end end


# Refresh the configuration for this server. Is thread-safe since the
# periodic refresh is invoked from another thread in order not to continue
# blocking operations on the current thread.
#
# @example Refresh the server.
# server.refresh!
#
# @note Is mutable in that the underlying server description can get
# mutated on this call.
#
# @return [ Server::Description ] The updated server description.
#
# @since 3.0.0
def refresh! def refresh!
mutex.synchronize do mutex.synchronize do
# Update the server description here. For changes in the description to description.update!(dispatch([ refresh_command ]))
# the previous we need to fire events.
#
# refreshed = Description.new(read(refresh_command))
#
# publish(Event::SERVER_ADDED, address)
# publish(Event::SERVER_REMOVED, address)
end end
end end


Expand Down Expand Up @@ -108,16 +117,23 @@ def refresh_interval


private private


def initialize_description!
# @description = Description.new(dispatch([ refresh_command ]))
# subscribe_to(description, Event::HOST_ADDED, Event::HostAdded.new(self))
# subscribe_to(description, Event::HOST_REMOVED, Event::HostRemoved.new(self))
end

def pool def pool
@pool ||= Pool.get(self) @pool ||= Pool.get(self)
end end


# @todo: Need to sort out read preference here.
def refresh_command def refresh_command
Protocol::Query.new( Protocol::Query.new(
Database::ADMIN, Database::ADMIN,
Database::COMMAND, Database::COMMAND,
STATUS, STATUS,
:limit => -1, :read => cluster.client.read_preference :limit => -1
) )
end end


Expand Down
36 changes: 36 additions & 0 deletions lib/mongo/server/description.rb
Expand Up @@ -20,6 +20,7 @@ class Server
# #
# @since 3.0.0 # @since 3.0.0
class Description class Description
include Event::Publisher


# Constant for reading arbiter info from config. # Constant for reading arbiter info from config.
# #
Expand Down Expand Up @@ -207,6 +208,41 @@ def secondary?
def set_name def set_name
config[SET_NAME] config[SET_NAME]
end end

# Update this description with a new description. Will fire the
# necessary events depending on what has changed from the old description
# to the new one.
#
# @example Update the description with the new config.
# description.update!({ "ismaster" => false })
#
# @note This modifies the state of the description.
#
# @param [ Hash ] new_config The new configuration.
#
# @return [ Description ] The updated description.
#
# @since 3.0.0
def update!(new_config)
find_new_servers(new_config)
find_removed_servers(new_config)
@config = new_config
self
end

private

def find_new_servers(new_config)
new_config[HOSTS].each do |host|
publish(Event::HOST_ADDED, host) unless hosts.include?(host)
end
end

def find_removed_servers(new_config)
hosts.each do |host|
publish(Event::HOST_REMOVED, host) unless new_config[HOSTS].include?(host)
end
end
end end
end end
end end
7 changes: 2 additions & 5 deletions spec/mongo/client_spec.rb
Expand Up @@ -194,15 +194,12 @@
describe '#inspect' do describe '#inspect' do


let(:client) do let(:client) do
described_class.new( described_class.new(['127.0.0.1:27017'], :read => :primary)
['1.0.0.1:2', '1.0.0.1:1'],
:read => :primary
)
end end


it 'returns the cluster information' do it 'returns the cluster information' do
expect(client.inspect).to eq( expect(client.inspect).to eq(
"<Mongo::Client:0x#{client.object_id} cluster=1.0.0.1:2, 1.0.0.1:1>" "<Mongo::Client:0x#{client.object_id} cluster=127.0.0.1:27017>"
) )
end end
end end
Expand Down
20 changes: 20 additions & 0 deletions spec/mongo/event/host_added_spec.rb
@@ -0,0 +1,20 @@
require 'spec_helper'

describe Mongo::Event::HostAdded do

describe '#handle' do

let(:server) do
double('server')
end

let(:handler) do
described_class.new(server)
end

it 'publishes the event from the server' do
expect(server).to receive(:publish).with(Mongo::Event::SERVER_ADDED, 'test')
handler.handle('test')
end
end
end
20 changes: 20 additions & 0 deletions spec/mongo/event/host_removed_spec.rb
@@ -0,0 +1,20 @@
require 'spec_helper'

describe Mongo::Event::HostRemoved do

describe '#handle' do

let(:server) do
double('server')
end

let(:handler) do
described_class.new(server)
end

it 'publishes the event from the server' do
expect(server).to receive(:publish).with(Mongo::Event::SERVER_REMOVED, 'test')
handler.handle('test')
end
end
end

0 comments on commit fcf075f

Please sign in to comment.