minor fixes and doc updates. :sync is default refresh mode.

This commit is contained in:
Kyle Banker 2011-09-15 18:44:02 -04:00
parent 3e3f05813a
commit 63c91af1b1
4 changed files with 51 additions and 24 deletions

View File

@ -15,10 +15,10 @@ cache the replica set topology as reported by the given seed node and use that i
### Read slaves
If you want to read from a seconday node, you can pass :read_secondary => true to ReplSetConnection#new.
If you want to read from a secondary node, you can pass :read => :secondary to ReplSetConnection#new.
@connection = ReplSetConnection.new(['n1.mydb.net', 27017], ['n2.mydb.net', 27017], ['n3.mydb.net', 27017],
:read_secondary => true)
:read => :secondary)
A random secondary will be chosen to be read from. In a typical multi-process Ruby application, you'll have a good distribution of reads across secondary nodes.
@ -32,6 +32,27 @@ If the client decides to retry, it's not guaranteed that another member of the r
The driver will essentially cycle through all known seed addresses until a node identifies itself as master.
### Refresh mode
You can now specify a refresh mode and refresh interval for a replica set connection. This will help to ensure that
changes to a replica set's configuration are quickly reflected on the driver side. Refresh mode is
enabled in synchronous mode by default. Here's how to specify this explicitly:
@connection = ReplSetConnection.new(['n1.mydb.net', 27017], :refresh_mode => :sync)
If you want to refresh to happen via a background thread, use the `:async` mode:
@connection = ReplSetConnection.new(['n1.mydb.net', 27017], :refresh_mode => :async)
If you want to change the default refresh interval of 90 seconds, you can do so like this:
@connection = ReplSetConnection.new(['n1.mydb.net', 27017], :refresh_mode => :async,
:refresh_interval => 60)
You can also disable refresh mode altogether:
@connection = ReplSetConnection.new(['n1.mydb.net', 27017], :refresh_mode => false)
### Recovery
Driver users may wish to wrap their database calls with failure recovery code. Here's one possibility, which will attempt to connection

View File

@ -1,4 +1,4 @@
# Tailable in Ruby
# Tailable cursors in Ruby
Tailable cursors are cursors that remain open even after they've returned
a final result. This way, if more documents are added to a collection (i.e.,

View File

@ -24,7 +24,7 @@ module Mongo
class ReplSetConnection < Connection
attr_reader :nodes, :secondaries, :arbiters, :secondary_pools,
:replica_set_name, :read_pool, :seeds, :tags_to_pools,
:refresh_interval, :background_refresh
:refresh_interval, :refresh_mode
# Create a connection to a MongoDB replica set.
#
@ -46,7 +46,7 @@ module Mongo
# objects created from this connection object. If +:secondary+ is chosen, reads will be sent
# to one of the closest available secondary nodes. If a secondary node cannot be located, the
# read will be sent to the primary.
# @option options [Logger, #debug] :logger (nil) Logger instance to receive driver operation log.
# @option options [Logger] :logger (nil) Logger instance to receive driver operation log.
# @option options [Integer] :pool_size (1) The maximum number of socket connections allowed per
# connection pool. Note: this setting is relevant only for multi-threaded applications.
# @option options [Float] :pool_timeout (5.0) When all of the connections a pool are checked out,
@ -57,15 +57,15 @@ module Mongo
# @option opts [Float] :connect_timeout (nil) The number of seconds to wait before timing out a
# connection attempt.
# @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
# @option opts [Boolean] :background_refresh (false) Set this to true to enable a background thread that
# @option opts [Boolean] :refresh_mode (:sync) Set this to :async to enable a background thread that
# periodically updates the state of the connection. If, for example, you initially connect while a secondary
# is down, :background_refresh will reconnect to that secondary behind the scenes to
# prevent you from having to reconnect manually. If set to +false+, background refresh will happen
# synchronously.
# @option opts [Integer] :refresh_interval (90) If :background_refresh is enabled, this is the number of seconds
# that the background thread will sleep between calls to check the replica set's state.
# is down, this will reconnect to that secondary behind the scenes to
# prevent you from having to reconnect manually. If set to :sync, refresh will happen
# synchronously. If +false+, no automatic refresh will occur unless there's a connection failure.
# @option opts [Integer] :refresh_interval (90) If :refresh_mode is enabled, this is the number of seconds
# between calls to check the replica set's state.
# @option opts [Boolean] :require_primary (true) If true, require a primary node for the connection
# to succeed. Otherwise, connection will succeed as long as there's at least one secondary.
# to succeed. Otherwise, connection will succeed as long as there's at least one secondary node.
#
# @example Connect to a replica set and provide two seed nodes. Note that the number of seed nodes does
# not have to be equal to the number of replica set members. The purpose of seed nodes is to permit
@ -120,9 +120,14 @@ module Mongo
@arbiters = []
# Refresh
@background_refresh = opts.fetch(:background_refresh, false)
@refresh_mode = opts.fetch(:refresh_mode, :sync)
@refresh_interval = opts[:refresh_interval] || 90
if ![:sync, :async, false].include?(@refresh_mode)
raise MongoArgumentError,
"Refresh mode must be one of :sync, :async, or false."
end
# Are we allowing reads from secondaries?
if opts[:read_secondary]
warn ":read_secondary options has now been deprecated and will " +
@ -165,14 +170,14 @@ module Mongo
# Initiate a connection to the replica set.
def connect
log(:debug, "Connecting...")
log(:info, "Connecting...")
sync_synchronize(:EX) do
return if @connected
manager = PoolManager.new(self, @seeds)
manager.connect
update_config(manager)
initiate_background_refresh
initiate_refresh_mode
if @require_primary && @primary.nil? #TODO: in v2.0, we'll let this be optional and do a lazy connect.
raise ConnectionFailure, "Failed to connect to primary node."
@ -210,7 +215,7 @@ module Mongo
return if sync_exclusive?
sync_synchronize(:EX) do
log(:debug, "Refreshing...")
log(:info, "Refreshing...")
@background_manager ||= PoolManager.new(self, @seeds)
@background_manager.connect
update_config(@background_manager)
@ -220,11 +225,12 @@ module Mongo
end
def connected?
@primary_pool || @read_pool
!@primary_pool.nil? || !@read_pool.nil?
end
# @deprecated
def connecting?
warn "ReplSetConnection#connecting? is deprecated and will be removed in v2.0."
false
end
@ -333,8 +339,8 @@ module Mongo
private
def initiate_background_refresh
if @background_refresh
def initiate_refresh_mode
if @refresh_mode == :async
return if @refresh_thread && @refresh_thread.alive?
@refresh_thread = Thread.new do
while true do
@ -342,9 +348,9 @@ module Mongo
refresh
end
end
else
@last_refresh = Time.now
end
@last_refresh = Time.now
end
# Checkout a socket for reading (i.e., a secondary node).
@ -444,8 +450,8 @@ module Mongo
end
# Refresh synchronously every @refresh_interval seconds
# if @background_refresh is false.
if !@background_refresh &&
# if synchronous refresh mode is enabled.
if @refresh_mode == :sync &&
((Time.now - @last_refresh) > @refresh_interval)
refresh
end

View File

@ -69,7 +69,7 @@ module Mongo
def inspect
"#<Mongo::Pool:0x#{self.object_id.to_s(16)} @host=#{@host} @port=#{port} " +
"@ping_time=#{ping_time} #{@checked_out.size}/#{@size} sockets available.>"
"@ping_time=#{@ping_time} #{@checked_out.size}/#{@size} sockets available.>"
end
def host_string