Skip to content

Commit cc5bfcf

Browse files
authored
Housekeeping for less complexity and more readability (#18)
1 parent a3fcedf commit cc5bfcf

File tree

2 files changed

+72
-82
lines changed

2 files changed

+72
-82
lines changed

lib/dns_cluster.ex

Lines changed: 30 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -37,49 +37,6 @@ defmodule DNSCluster do
3737
use GenServer
3838
require Logger
3939

40-
defmodule Resolver do
41-
@moduledoc false
42-
43-
require Record
44-
Record.defrecord(:hostent, Record.extract(:hostent, from_lib: "kernel/include/inet.hrl"))
45-
46-
def basename(node_name) when is_atom(node_name) do
47-
[basename, _] = String.split(to_string(node_name), "@")
48-
basename
49-
end
50-
51-
def connect_node(node_name) when is_atom(node_name), do: Node.connect(node_name)
52-
53-
def list_nodes, do: Node.list(:visible)
54-
55-
def lookup(query, type) when is_binary(query) and type in [:a, :aaaa] do
56-
case :inet_res.getbyname(~c"#{query}", type) do
57-
{:ok, hostent(h_addr_list: addr_list)} -> addr_list
58-
{:error, _} -> []
59-
end
60-
end
61-
62-
def lookup(query, type) when is_binary(query) and type in [:srv] do
63-
case :inet_res.getbyname(~c"#{query}", type) do
64-
{:ok, hostent(h_addr_list: srv_list)} ->
65-
lookup_hosts(srv_list)
66-
67-
{:error, _} ->
68-
[]
69-
end
70-
end
71-
72-
defp lookup_hosts(srv_list) do
73-
srv_list
74-
|> Enum.flat_map(fn {_prio, _weight, _port, host_name} ->
75-
case :inet.gethostbyname(host_name) do
76-
{:ok, hostent(h_addr_list: addr_list)} -> addr_list
77-
{:error, _} -> []
78-
end
79-
end)
80-
end
81-
end
82-
8340
@doc ~S"""
8441
Starts DNS based cluster discovery.
8542
@@ -112,24 +69,18 @@ defmodule DNSCluster do
11269

11370
@impl true
11471
def init(opts) do
115-
resource_types = Keyword.get(opts, :resource_types, [:a, :aaaa])
116-
11772
case Keyword.fetch(opts, :query) do
11873
{:ok, :ignore} ->
11974
:ignore
12075

12176
{:ok, query} ->
122-
if not valid_query?(query) do
123-
raise ArgumentError,
124-
"expected :query to be a string, {basename, query}, or list, got: #{inspect(query)}"
125-
end
77+
validate_query!(query)
12678

127-
if not valid_resource_types?(resource_types) do
128-
raise ArgumentError,
129-
"expected :resource_types to be a subset of [:a, :aaaa, :srv], got: #{inspect(resource_types)}"
130-
end
79+
resource_types = Keyword.get(opts, :resource_types, [:a, :aaaa])
80+
validate_resource_types!(resource_types)
13181

13282
warn_on_invalid_dist()
83+
13384
resolver = Keyword.get(opts, :resolver, Resolver)
13485

13586
state = %{
@@ -198,43 +149,40 @@ defmodule DNSCluster do
198149
end
199150

200151
defp discover_ips(%{resolver: resolver, query: queries, resource_types: resource_types} = state) do
201-
resource_types
202-
|> Enum.flat_map(fn type ->
203-
Enum.flat_map(queries, fn query ->
204-
{basename, query} =
205-
case query do
206-
{basename, query} ->
207-
# use the user-specified basename
208-
{basename, query}
209-
210-
query when is_binary(query) ->
211-
# no basename specified, use host basename
212-
{state.basename, query}
213-
end
214-
215-
for addr <- resolver.lookup(query, type) do
216-
{basename, addr}
217-
end
218-
end)
219-
end)
152+
for resource_type <- resource_types,
153+
query <- queries,
154+
basename = basename_from_query_or_state(query, state),
155+
addr <- resolver.lookup(query, resource_type) do
156+
{basename, addr}
157+
end
220158
|> Enum.uniq()
221159
|> Enum.map(fn {basename, addr} -> {basename, to_string(:inet.ntoa(addr))} end)
222160
end
223161

224-
defp valid_query?(list) do
225-
list
162+
defp basename_from_query_or_state({basename, _query}, _state), do: basename
163+
defp basename_from_query_or_state(_query, %{basename: basename}), do: basename
164+
165+
defp validate_query!(query) do
166+
query
226167
|> List.wrap()
227-
|> Enum.all?(fn
228-
string when is_binary(string) -> true
229-
{basename, query} when is_binary(basename) and is_binary(query) -> true
230-
_ -> false
168+
|> Enum.each(fn
169+
string when is_binary(string) ->
170+
true
171+
172+
{basename, query} when is_binary(basename) and is_binary(query) ->
173+
true
174+
175+
_ ->
176+
raise ArgumentError,
177+
"expected :query to be a string, {basename, query}, or list, got: #{inspect(query)}"
231178
end)
232179
end
233180

234-
defp valid_resource_types?([]), do: false
235-
236-
defp valid_resource_types?(resource_types) do
237-
resource_types -- @valid_resource_types == []
181+
defp validate_resource_types!(resource_types) do
182+
if resource_types == [] or resource_types -- @valid_resource_types != [] do
183+
raise ArgumentError,
184+
"expected :resource_types to be a subset of [:a, :aaaa, :srv], got: #{inspect(resource_types)}"
185+
end
238186
end
239187

240188
defp warn_on_invalid_dist do

lib/dns_cluster/resolver.ex

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
defmodule DNSCluster.Resolver do
2+
@moduledoc false
3+
4+
require Record
5+
Record.defrecord(:hostent, Record.extract(:hostent, from_lib: "kernel/include/inet.hrl"))
6+
7+
def basename(node_name) when is_atom(node_name) do
8+
[basename, _] = String.split(to_string(node_name), "@")
9+
basename
10+
end
11+
12+
def connect_node(node_name) when is_atom(node_name), do: Node.connect(node_name)
13+
14+
def list_nodes, do: Node.list(:visible)
15+
16+
def lookup(query, type) when is_binary(query) and type in [:a, :aaaa] do
17+
case :inet_res.getbyname(~c"#{query}", type) do
18+
{:ok, hostent(h_addr_list: addr_list)} -> addr_list
19+
{:error, _} -> []
20+
end
21+
end
22+
23+
def lookup(query, type) when is_binary(query) and type in [:srv] do
24+
case :inet_res.getbyname(~c"#{query}", type) do
25+
{:ok, hostent(h_addr_list: srv_list)} ->
26+
lookup_hosts(srv_list)
27+
28+
{:error, _} ->
29+
[]
30+
end
31+
end
32+
33+
defp lookup_hosts(srv_list) do
34+
srv_list
35+
|> Enum.flat_map(fn {_prio, _weight, _port, host_name} ->
36+
case :inet.gethostbyname(host_name) do
37+
{:ok, hostent(h_addr_list: addr_list)} -> addr_list
38+
{:error, _} -> []
39+
end
40+
end)
41+
end
42+
end

0 commit comments

Comments
 (0)