defmodule Ravix.Connection.ServerNode do
@moduledoc """
State of a RavenDB connection executor node
- store: Atom of the RavenDB Store, E.g: Ravix.Test.Store
- url: URL of this node
- port: port of this node
- conn: TCP Connection State
- ssl_config: User SSL certificate config for this node
- requests: Currently executing request calls to RavenDB
- protocol: http or https
- database: For which database is this executor
- cluster_tag: Tag of this node in the RavenDB cluster
- min_pool_size: Minimum amount of parallel connections to the node
- max_pool_size: Maximum amount of parallel connections to the node
- timeout: Maximum amount of time to wait for a execution (in ms)
- opts: General node Options
"""
defstruct store: nil,
url: nil,
port: nil,
conn: nil,
ssl_config: nil,
requests: %{},
request_options: %{},
protocol: nil,
database: nil,
cluster_tag: nil,
min_pool_size: 1,
max_pool_size: 10,
timeout: 15000,
opts: []
alias Ravix.Connection.ServerNode
alias Ravix.Connection.State, as: ConnectionState
@type t :: %ServerNode{
store: atom(),
url: String.t(),
port: non_neg_integer(),
conn: Mint.HTTP.t() | nil,
ssl_config: Keyword.t() | nil,
requests: map(),
request_options: map(),
protocol: atom(),
database: String.t(),
cluster_tag: String.t() | nil,
min_pool_size: non_neg_integer(),
max_pool_size: non_neg_integer(),
timeout: non_neg_integer(),
opts: keyword()
}
@doc """
Creates a new node state from the url, database name and ssl certificate
"""
@spec from_url(binary | URI.t(), ConnectionState.t()) :: ServerNode.t()
def from_url(url, %ConnectionState{
ssl_config: ssl_config,
database: database,
max_pool_size: max_pool_size,
min_pool_size: min_pool_size
}) do
parsed_url = URI.new!(url)
%ServerNode{
url: parsed_url.host,
port: parsed_url.port,
protocol: String.to_atom(parsed_url.scheme),
ssl_config: ssl_config,
min_pool_size: min_pool_size,
max_pool_size: max_pool_size,
database: database
}
end
@doc """
Create a new node state based on the RavenDB Topology response
"""
@spec from_api_response(map) :: ServerNode.t()
def from_api_response(node_response) do
parsed_url = URI.new!(node_response["Url"])
%ServerNode{
url: parsed_url.host,
port: parsed_url.port,
protocol: String.to_atom(parsed_url.scheme),
database: node_response["Database"],
cluster_tag: node_response["ClusterTag"]
}
end
@doc """
Helper method to build the url for Database specific API requests
"""
@spec node_url(ServerNode.t()) :: String.t()
def node_url(%ServerNode{} = server_node),
do: "/databases/#{server_node.database}"
@spec retry_on_stale?(ServerNode.t()) :: boolean()
def retry_on_stale?(%ServerNode{} = node), do: Keyword.get(node.opts, :retry_on_stale, false)
defimpl String.Chars, for: Ravix.Connection.ServerNode do
def to_string(nil) do
""
end
def to_string(node) do
"#{node.protocol}://#{node.url}:#{node.port}"
end
end
end