Current section

Files

Jump to
mongodb_driver lib mongo server_description.ex
Raw

lib/mongo/server_description.ex

defmodule Mongo.ServerDescription do
@moduledoc false
# see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#serverdescription
@type type :: :standalone | :mongos | :possible_primary | :rs_primary |
:rs_secondary | :rs_arbiter | :rs_other | :rs_ghost | :unknown
@type t :: %{
address: String.t | nil,
error: String.t | nil,
round_trip_time: non_neg_integer | nil,
last_write_date: DateTime.t,
op_time: BSON.ObjectId.t | nil,
type: type,
min_wire_version: non_neg_integer,
max_wire_version: non_neg_integer,
me: String.t | nil,
hosts: [String.t],
passives: [String.t],
arbiters: [String.t],
tag_set: %{String.t => String.t},
set_name: String.t | nil,
set_version: non_neg_integer | nil,
election_id: BSON.ObjectId.t | nil,
primary: String.t | nil,
last_update_time: non_neg_integer,
max_bson_object_size: non_neg_integer,
max_message_size_bytes: non_neg_integer,
max_write_batch_size: non_neg_integer,
compression: String.t | nil,
read_only: boolean(),
logical_session_timeout: non_neg_integer
}
def defaults(map \\ %{}) do
Map.merge(%{
address: "localhost:27017",
error: nil,
round_trip_time: nil,
last_write_date: nil,
op_time: nil,
type: :unknown,
min_wire_version: 0,
max_wire_version: 0,
me: nil,
hosts: [],
passives: [],
arbiters: [],
tag_set: %{},
set_name: nil,
set_version: nil,
election_id: nil,
primary: nil,
last_update_time: 0,
max_bson_object_size: 16_777_216,
max_message_size_bytes: 48_000_000,
max_write_batch_size: 100_000,
compression: nil,
read_only: false,
logical_session_timeout: 30
}, map)
end
def from_is_master_error(address, error) do
defaults(%{
address: address,
error: error
})
end
# see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#parsing-an-ismaster-response
def from_is_master(address, rtt, finish_time, is_master_reply) do
%{
address: address,
round_trip_time: rtt,
type: determine_server_type(is_master_reply),
last_write_date: get_in(is_master_reply,["lastWrite", "lastWriteDate"]),
op_time: get_in(is_master_reply, ["lastWrite", "opTime"]),
last_update_time: finish_time,
min_wire_version: is_master_reply["minWireVersion"] || 0,
max_wire_version: is_master_reply["maxWireVersion"] || 0,
me: is_master_reply["me"],
hosts: (is_master_reply["hosts"] || []) |> Enum.map(&String.downcase/1),
passives: (is_master_reply["passives"] || []) |> Enum.map(&String.downcase/1),
arbiters: (is_master_reply["arbiters"] || []) |> Enum.map(&String.downcase/1),
tag_set: is_master_reply["tags"] || %{},
set_name: is_master_reply["setName"],
set_version: is_master_reply["setVersion"],
election_id: is_master_reply["electionId"],
primary: is_master_reply["primary"],
max_bson_object_size: (is_master_reply["maxBsonObjectSize"] || 16_777_216),
max_message_size_bytes: (is_master_reply["maxMessageSizeBytes"] || 48_000_000),
max_write_batch_size: (is_master_reply["maxWriteBatchSize"] || 100_000),
compression: is_master_reply["compression"],
read_only: (is_master_reply["readOnly"] || false),
logical_session_timeout: is_master_reply["logicalSessionTimeoutMinutes"] || 30
}
end
# see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#type
defp determine_server_type(%{"ok" => n}) when n != 1, do: :unknown
defp determine_server_type(%{"msg" => "isdbgrid"}), do: :mongos
defp determine_server_type(%{"isreplicaset" => true}), do: :rs_ghost
defp determine_server_type(%{"setName" => set_name} = is_master_reply) when set_name != nil do
case is_master_reply do
%{"ismaster" => true} -> :rs_primary
%{"secondary" => true} -> :rs_secondary
%{"arbiterOnly" => true} -> :rs_arbiter
_ -> :rs_other
end
end
defp determine_server_type(_), do: :standalone
end