123456789_123456789_123456789_123456789_123456789_

Module: Mongo::Operation::ReadPreferenceSupported Private

Do not use. This module is for internal use only.
Relationships & Source Files
Defined in: lib/mongo/operation/shared/read_preference_supported.rb

Overview

Read preference handling for pre-OP_MSG operation implementations.

This module is not used by OP_MSG operation classes (those deriving from OpMsgBase). Instead, read preference for those classes is handled in SessionsSupported module.

Since:

  • 2.5.2

Instance Method Summary

Instance Method Details

#add_read_preference_legacy(sel, connection) ⇒ Hash (private)

Adds $readPreference field to the command document.

$readPreference is only sent when the server is a mongos, following the rules described in github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#passing-read-preference-to-mongos. The topology does not matter for figuring out whether to send $readPreference since the decision is always made based on server type.

$readPreference is not sent to pre-OP_MSG replica set members.

Parameters:

  • sel (Hash)

    Existing command document.

  • connection (Server::Connection)

    The connection that the operation will be executed on.

Returns:

  • (Hash)

    New command document to send to the server.

Since:

  • 2.5.2

[ GitHub ]

  
# File 'lib/mongo/operation/shared/read_preference_supported.rb', line 98

def add_read_preference_legacy(sel, connection)
  if read && (
    connection.description.mongos? || connection.description.load_balancer?
  ) && read_pref = read.to_mongos
    # If the read preference contains only mode and mode is secondary
    # preferred and we are sending to a pre-OP_MSG server, this read
    # preference is indicated by the :secondary_ok wire protocol flag
    # and $readPreference command parameter isn't sent.
    if read_pref != {mode: 'secondaryPreferred'}
      Mongo::Lint.validate_camel_case_read_preference(read_pref)
      sel = sel[:$query] ? sel : {:$query => sel}
      sel = sel.merge(:$readPreference => read_pref)
    end
  end
  sel
end

#add_secondary_ok_flag?(connection) ⇒ true | false (private)

Whether to add the :secondary_ok flag to the request based on the read preference specified in the operation or implied by the topology that the connection’s server is a part of.

Parameters:

  • connection (Server::Connection)

    The connection that the operation will be executed on.

Returns:

  • (true | false)

    Whether the :secondary_ok flag should be added.

Since:

  • 2.5.2

[ GitHub ]

  
# File 'lib/mongo/operation/shared/read_preference_supported.rb', line 59

def add_secondary_ok_flag?(connection)
  # https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#topology-type-single
  if connection.description.standalone?
    # Read preference is never sent to standalones.
    false
  elsif connection.server.cluster.single?
    # In Single topology the driver forces primaryPreferred read
    # preference mode (via the secondary_ok flag, in case of old servers)
    # so that the query is satisfied.
    true
  else
    # In replica sets and sharded clusters, read preference is passed
    # to the server if one is specified by the application, and there
    # is no default.
    read && read.secondary_ok? || false
  end
end

#command(connection) (private)

Since:

  • 2.5.2

[ GitHub ]

  
# File 'lib/mongo/operation/shared/read_preference_supported.rb', line 77

def command(connection)
  sel = super
  add_read_preference_legacy(sel, connection)
end

#options(connection) ⇒ Hash (private)

Get the options for executing the operation on a particular connection.

Parameters:

  • connection (Server::Connection)

    The connection that the operation will be executed on.

Returns:

  • (Hash)

    The options.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/shared/read_preference_supported.rb', line 41

def options(connection)
  options = super
  if add_secondary_ok_flag?(connection)
    flags = options[:flags]&.dup || []
    flags << :secondary_ok
    options = options.merge(flags: flags)
  end
  options
end