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