Class: Mongo::Protocol::Message Abstract

Inherits:
Object
  • Object
show all
Includes:
Serializers
Defined in:
lib/mongo/protocol/message.rb

Overview

This class is abstract.

A base class providing functionality required by all messages in the MongoDB wire protocol. It provides a minimal DSL for defining typed fields to enable serialization and deserialization over the wire.

Examples:

class WireProtocolMessage < Message

  private

  def op_code
    1234
  end

  FLAGS = [:first_bit, :bit_two]

  # payload
  field :flags, BitVector.new(FLAGS)
  field :namespace, CString
  field :document, Document
  field :documents, Document, true
end

Direct Known Subclasses

Delete, GetMore, Insert, KillCursors, Query, Reply, Update

Constant Summary

BATCH_SIZE =

The batch size constant.

Since:

  • 2.2.0

'batchSize'.freeze
COLLECTION =

The collection constant.

Since:

  • 2.2.0

'collection'.freeze
LIMIT =

The limit constant.

Since:

  • 2.2.0

'limit'.freeze
ORDERED =

The ordered constant.

Since:

  • 2.2.0

'ordered'.freeze
Q =

The q constant.

Since:

  • 2.2.0

'q'.freeze
MAX_MESSAGE_SIZE =

Default max message size of 48MB.

Since:

  • 2.2.1

50331648.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Message

:nodoc:



80
81
82
# File 'lib/mongo/protocol/message.rb', line 80

def initialize(*args) # :nodoc:
  @request_id = nil
end

Instance Attribute Details

#request_idFixnum (readonly)

Returns the request id for the message

Returns:

  • (Fixnum)

    The request id for this message



78
79
80
# File 'lib/mongo/protocol/message.rb', line 78

def request_id
  @request_id
end

Class Method Details

.deserialize(io, max_message_size = MAX_MESSAGE_SIZE, expected_response_to = nil) ⇒ Message

Deserializes messages from an IO stream

Parameters:

  • max_message_size (Integer) (defaults to: MAX_MESSAGE_SIZE)

    The max message size.

  • io (IO)

    Stream containing a message

Returns:

  • (Message)

    Instance of a Message class



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/mongo/protocol/message.rb', line 116

def self.deserialize(io, max_message_size = MAX_MESSAGE_SIZE, expected_response_to = nil)
  length, _request_id, response_to, _op_code = deserialize_header(BSON::ByteBuffer.new(io.read(16)))

  # Protection from potential DOS man-in-the-middle attacks. See
  # DRIVERS-276.
  if length > (max_message_size || MAX_MESSAGE_SIZE)
    raise Error::MaxMessageSize.new(max_message_size)
  end

  # Protection against returning the response to a previous request. See
  # RUBY-1117
  if expected_response_to && response_to != expected_response_to
    raise Error::UnexpectedResponse.new(expected_response_to, response_to)
  end

  buffer = BSON::ByteBuffer.new(io.read(length - 16))
  message = allocate

  fields.each do |field|
    if field[:multi]
      deserialize_array(message, buffer, field)
    else
      deserialize_field(message, buffer, field)
    end
  end
  message
end

Instance Method Details

#==(other) ⇒ true, false Also known as: eql?

Tests for equality between two wire protocol messages by comparing class and field values.

Parameters:

Returns:

  • (true, false)

    The equality of the messages.



149
150
151
152
153
154
155
156
# File 'lib/mongo/protocol/message.rb', line 149

def ==(other)
  return false if self.class != other.class
  fields.all? do |field|
    name = field[:name]
    instance_variable_get(name) ==
      other.instance_variable_get(name)
  end
end

#hashFixnum

Creates a hash from the values of the fields of a message.

Returns:

  • (Fixnum)

    The hash code for the message.



162
163
164
# File 'lib/mongo/protocol/message.rb', line 162

def hash
  fields.map { |field| instance_variable_get(field[:name]) }.hash
end

#replyable?false

The default for messages is not to require a reply after sending a message to the server.

Examples:

Does the message require a reply?

message.replyable?

Returns:

  • (false)

    The default is to not require a reply.

Since:

  • 2.0.0



93
94
95
# File 'lib/mongo/protocol/message.rb', line 93

def replyable?
  false
end

#serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil) ⇒ String Also known as: to_s

Serializes message into bytes that can be sent on the wire

Parameters:

  • buffer (String) (defaults to: BSON::ByteBuffer.new)

    buffer where the message should be inserted

Returns:

  • (String)

    buffer containing the serialized message



101
102
103
104
105
106
# File 'lib/mongo/protocol/message.rb', line 101

def serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil)
  start = buffer.length
  serialize_header(buffer)
  serialize_fields(buffer, max_bson_size)
  buffer.replace_int32(start, buffer.length - start)
end

#set_request_idFixnum

Generates a request id for a message

Returns:

  • (Fixnum)

    a request id used for sending a message to the server. The server will put this id in the response_to field of a reply.



171
172
173
174
175
# File 'lib/mongo/protocol/message.rb', line 171

def set_request_id
  @@id_lock.synchronize do
    @request_id = @@request_id += 1
  end
end