Packages
redix
0.11.2
1.6.0
1.5.3
1.5.2
1.5.1
1.5.0
1.4.2
1.4.1
1.4.0
1.3.0
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
retired
1.1.0
1.0.0
0.11.2
0.11.1
0.11.0
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.0
Fast, pipelined, resilient Redis driver for Elixir.
Current section
Files
Jump to
Current section
Files
lib/redix/start_options.ex
defmodule Redix.StartOptions do
@moduledoc false
@default_sentinel_options [
timeout: 500,
socket_opts: [],
ssl: false,
role: :primary
]
@default_options [
socket_opts: [],
ssl: false,
sync_connect: false,
backoff_initial: 500,
backoff_max: 30000,
exit_on_disconnection: false,
timeout: 5000
]
@allowed_options [
:host,
:port,
:database,
:password,
:name,
:sentinel,
:hibernate_after,
:debug,
:spawn_opt
] ++
Keyword.keys(@default_options)
def sanitize(options) when is_list(options) do
@default_options
|> Keyword.merge(options)
|> assert_only_known_options()
|> maybe_sanitize_sentinel_opts()
|> maybe_sanitize_host_and_port()
end
defp assert_only_known_options(options) do
Enum.each(options, fn {key, _value} ->
unless key in @allowed_options do
raise ArgumentError, "unknown option: #{inspect(key)}"
end
end)
options
end
defp maybe_sanitize_sentinel_opts(options) do
case Keyword.fetch(options, :sentinel) do
{:ok, sentinel_opts} ->
Keyword.put(options, :sentinel, sanitize_sentinel_opts(options, sentinel_opts))
:error ->
options
end
end
defp sanitize_sentinel_opts(opts, sentinel_opts) do
sentinel_opts =
case Keyword.fetch(sentinel_opts, :sentinels) do
{:ok, sentinels} when is_list(sentinels) and sentinels != [] ->
sentinels = Enum.map(sentinels, &normalize_sentinel_address(&1, sentinel_opts))
Keyword.replace!(sentinel_opts, :sentinels, sentinels)
{:ok, sentinels} ->
raise ArgumentError,
"the :sentinels option inside :sentinel must be a non-empty list, got: " <>
inspect(sentinels)
:error ->
raise ArgumentError, "the :sentinels option is required inside :sentinel"
end
unless Keyword.has_key?(sentinel_opts, :group) do
raise ArgumentError, "the :group option is required inside :sentinel"
end
if Keyword.has_key?(opts, :host) or Keyword.has_key?(opts, :port) do
raise ArgumentError, ":host or :port can't be passed as option if :sentinel is used"
end
Keyword.merge(@default_sentinel_options, sentinel_opts)
end
defp normalize_sentinel_address(sentinel_uri, sentinel_opts) when is_binary(sentinel_uri) do
sentinel_uri |> Redix.URI.opts_from_uri() |> normalize_sentinel_address(sentinel_opts)
end
defp normalize_sentinel_address(opts, sentinel_opts) when is_list(opts) do
opts =
if opts[:host] do
Keyword.update!(opts, :host, &to_charlist/1)
else
raise ArgumentError, "a host should be specified for each sentinel"
end
unless opts[:port] do
raise ArgumentError, "a port should be specified for each sentinel"
end
Keyword.merge(Keyword.take(sentinel_opts, [:password]), opts)
end
defp normalize_sentinel_address(other, _sentinel_opts) do
raise ArgumentError,
"sentinel address should be specified as a URI or a keyword list, got: " <>
inspect(other)
end
defp maybe_sanitize_host_and_port(options) do
if Keyword.has_key?(options, :sentinel) do
options
else
{host, port} =
case {Keyword.get(options, :host, "localhost"), Keyword.fetch(options, :port)} do
{{:local, _unix_socket_path}, {:ok, port}} when port != 0 ->
raise ArgumentError,
"when using Unix domain sockets, the port must be 0, got: #{inspect(port)}"
{{:local, _unix_socket_path} = host, :error} ->
{host, 0}
{_host, {:ok, port}} when not is_integer(port) ->
raise ArgumentError,
"expected an integer as the value of the :port option, got: #{inspect(port)}"
{host, {:ok, port}} when is_binary(host) ->
{String.to_charlist(host), port}
{host, :error} when is_binary(host) ->
{String.to_charlist(host), 6379}
end
Keyword.merge(options, host: host, port: port)
end
end
end