class Mongo::Server::AppMetadata::Truncator

Implements the metadata truncation logic described in the handshake spec.

@api private

Constants

MAX_DOCUMENT_SIZE

The max application metadata document byte size.

Attributes

document[R]

@return [ BSON::Document ] the document being truncated.

Public Class Methods

new(document) click to toggle source

Creates a new Truncator instance and tries enforcing the maximum document size on the given document.

@param [ BSON::Document] document The document to (potentially)

truncate.

@note The document is modified in-place; if you wish to keep the

original unchanged, you must deep-clone it prior to sending it to
a truncator.
# File lib/mongo/server/app_metadata/truncator.rb, line 39
def initialize(document)
  @document = document
  try_truncate!
end

Public Instance Methods

ok?() click to toggle source

Whether the document fits within the required maximum document size.

@return [ true | false ] if the document is okay or not.

# File lib/mongo/server/app_metadata/truncator.rb, line 55
def ok?
  size <= MAX_DOCUMENT_SIZE
end
size() click to toggle source

The current size of the document, in bytes, as a serialized BSON document.

@return [ Integer ] the size of the document

# File lib/mongo/server/app_metadata/truncator.rb, line 48
def size
  @document.to_bson.to_s.length
end

Private Instance Methods

excess() click to toggle source

How many extra bytes must be trimmed before the document may be considered ok?.

@return [ Integer ] how many bytes larger the document is than the

maximum document size.
# File lib/mongo/server/app_metadata/truncator.rb, line 66
def excess
  size - MAX_DOCUMENT_SIZE
end
try_truncate!() click to toggle source

Attempt to truncate the document using the documented metadata priorities (see the handshake specification).

# File lib/mongo/server/app_metadata/truncator.rb, line 72
def try_truncate!
  %i[ env_fields os_fields env platform ].each do |target|
    break if ok?

    send(:"try_truncate_#{target}!")
  end
end
try_truncate_env!() click to toggle source

Remove the {{:env}} key from the document.

# File lib/mongo/server/app_metadata/truncator.rb, line 97
def try_truncate_env!
  @document.delete(:env)
end
try_truncate_env_fields!() click to toggle source

Attempt to truncate the keys in the {{:env}} subdocument.

# File lib/mongo/server/app_metadata/truncator.rb, line 87
def try_truncate_env_fields!
  try_truncate_hash(@document[:env], reserved: %w[ name ])
end
try_truncate_hash(hash, reserved: []) click to toggle source

A helper method for removing the keys of a Hash (in-place) until the document is the necessary size. The keys are considered in order (using the Hash's native key ordering), and each will be removed from the hash in turn, until the document is the necessary size.

Any keys in the {{reserved}} list will be ignored.

@param [ Hash | nil ] hash the Hash instance to consider. @param [ Array ] reserved the list of keys to ignore in the hash.

@note the hash parameter is modified in-place.

# File lib/mongo/server/app_metadata/truncator.rb, line 126
def try_truncate_hash(hash, reserved: [])
  return false unless hash

  keys = hash.keys - reserved
  keys.each do |key|
    hash.delete(key)

    return true if ok?
  end

  false
end
try_truncate_os_fields!() click to toggle source

Attempt to truncate the keys in the {{:os}} subdocument.

# File lib/mongo/server/app_metadata/truncator.rb, line 92
def try_truncate_os_fields!
  try_truncate_hash(@document[:os], reserved: %w[ type ])
end
try_truncate_platform!() click to toggle source

Attempt to truncate or remove the {{:platform}} key from the document.

# File lib/mongo/server/app_metadata/truncator.rb, line 82
def try_truncate_platform!
  @document.delete(:platform) unless try_truncate_string(@document[:platform])
end
try_truncate_string(string) click to toggle source

A helper method for truncating a string (in-place) by whatever {{#excess}} is required.

@param [ String ] string the string value to truncate.

@note the parameter is modified in-place.

# File lib/mongo/server/app_metadata/truncator.rb, line 107
def try_truncate_string(string)
  length = string&.length || 0

  return false if excess > length

  string[(length - excess)..-1] = ''
end