module Mongo::Operation::Executable

Shared executable behavior of operations.

@since 2.5.2 @api private

Public Instance Methods

do_execute(connection, context, options = {}) click to toggle source
# File lib/mongo/operation/shared/executable.rb, line 29
def do_execute(connection, context, options = {})
  session&.materialize_if_needed
  unpin_maybe(session, connection) do
    add_error_labels(connection, context) do
      add_server_diagnostics(connection) do
        get_result(connection, context, options).tap do |result|
          if session
            if session.in_transaction? &&
              connection.description.load_balancer?
            then
              if session.pinned_connection_global_id
                unless session.pinned_connection_global_id == connection.global_id
                  raise(
                    Error::InternalDriverError,
                    "Expected operation to use connection #{session.pinned_connection_global_id} but it used #{connection.global_id}"
                  )
                end
              else
                session.pin_to_connection(connection.global_id)
                connection.pin
              end
            end

            if session.snapshot? && !session.snapshot_timestamp
              session.snapshot_timestamp = result.snapshot_timestamp
            end
          end

          if result.has_cursor_id? &&
            connection.description.load_balancer?
          then
            if result.cursor_id == 0
              connection.unpin
            else
              connection.pin
            end
          end
          process_result(result, connection)
        end
      end
    end
  end
end
execute(connection, context:, options: {}) click to toggle source
# File lib/mongo/operation/shared/executable.rb, line 73
def execute(connection, context:, options: {})
  if Lint.enabled?
    unless connection.is_a?(Mongo::Server::Connection)
      raise Error::LintError, "Connection argument is of wrong type: #{connection}"
    end
  end

  do_execute(connection, context, options).tap do |result|
    validate_result(result, connection, context)
  end
end

Private Instance Methods

build_message(connection, context) click to toggle source

@param [ Mongo::Server::Connection ] connection The connection on which

the operation is performed.

@param [ Mongo::Operation::Context ] context The operation context.

# File lib/mongo/operation/shared/executable.rb, line 106
def build_message(connection, context)
  msg = message(connection)
  if server_api = context.server_api
    msg = msg.maybe_add_server_api(server_api)
  end
  msg
end
dispatch_message(connection, context, options = {}) click to toggle source

Returns a Protocol::Message or nil as reply.

# File lib/mongo/operation/shared/executable.rb, line 96
def dispatch_message(connection, context, options = {})
  message = build_message(connection, context)
  message = message.maybe_encrypt(connection, context)
  reply = connection.dispatch([ message ], context, options)
  [reply, connection.description, connection.global_id]
end
get_result(connection, context, options = {}) click to toggle source
# File lib/mongo/operation/shared/executable.rb, line 91
def get_result(connection, context, options = {})
  result_class.new(*dispatch_message(connection, context, options))
end
process_result(result, connection) click to toggle source
# File lib/mongo/operation/shared/executable.rb, line 114
def process_result(result, connection)
  connection.server.update_cluster_time(result)

  process_result_for_sdam(result, connection)

  if session
    session.process(result)
  end

  result
end
process_result_for_sdam(result, connection) click to toggle source
# File lib/mongo/operation/shared/executable.rb, line 126
def process_result_for_sdam(result, connection)
  if (result.not_master? || result.node_recovering?) &&
    connection.generation >= connection.server.pool.generation(service_id: connection.service_id)
  then
    if result.node_shutting_down?
      keep_pool = false
    else
      # Max wire version needs to be examined while the server is known
      keep_pool = connection.description.server_version_gte?('4.2')
    end

    connection.server.unknown!(
      keep_connection_pool: keep_pool,
      generation: connection.generation,
      service_id: connection.service_id,
      topology_version: result.topology_version,
    )

    connection.server.scan_semaphore.signal
  end
end
result_class() click to toggle source
# File lib/mongo/operation/shared/executable.rb, line 87
def result_class
  Result
end