Skip to content

Commit be07ca5

Browse files
author
Adriano Santos
committed
cluster resolver in debug mode
1 parent cd0f10e commit be07ca5

File tree

3 files changed

+171
-31
lines changed

3 files changed

+171
-31
lines changed

lib/spawn/cluster/cluster_resolver.ex

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
defmodule Spawn.Cluster.ClusterResolver do
2+
@moduledoc false
3+
4+
use GenServer
5+
use Cluster.Strategy
6+
import Cluster.Logger
7+
8+
alias Cluster.Strategy.State
9+
10+
@default_polling_interval 5_000
11+
12+
@impl true
13+
def start_link(args), do: GenServer.start_link(__MODULE__, args)
14+
15+
@impl true
16+
def init([%State{meta: nil} = state]) do
17+
init([%State{state | :meta => MapSet.new()}])
18+
end
19+
20+
def init([%State{} = state]) do
21+
{:ok, load(state), 0}
22+
end
23+
24+
@impl true
25+
def handle_info(:timeout, state) do
26+
handle_info(:load, state)
27+
end
28+
29+
def handle_info(:load, state) do
30+
{:noreply, load(state)}
31+
end
32+
33+
def handle_info(_, state) do
34+
{:noreply, state}
35+
end
36+
37+
defp load(%State{topology: topology, meta: meta} = state) do
38+
new_nodelist = MapSet.new(get_nodes(state))
39+
removed = MapSet.difference(meta, new_nodelist)
40+
41+
new_nodelist =
42+
case Cluster.Strategy.disconnect_nodes(
43+
topology,
44+
state.disconnect,
45+
state.list_nodes,
46+
MapSet.to_list(removed)
47+
) do
48+
:ok ->
49+
new_nodelist
50+
51+
{:error, bad_nodes} ->
52+
# Add back the nodes which should have been removed, but which couldn't be for some reason
53+
Enum.reduce(bad_nodes, new_nodelist, fn {n, _}, acc ->
54+
MapSet.put(acc, n)
55+
end)
56+
end
57+
58+
new_nodelist =
59+
case Cluster.Strategy.connect_nodes(
60+
topology,
61+
state.connect,
62+
state.list_nodes,
63+
MapSet.to_list(new_nodelist)
64+
) do
65+
:ok ->
66+
new_nodelist
67+
68+
{:error, bad_nodes} ->
69+
# Remove the nodes which should have been added, but couldn't be for some reason
70+
Enum.reduce(bad_nodes, new_nodelist, fn {n, _}, acc ->
71+
MapSet.delete(acc, n)
72+
end)
73+
end
74+
75+
Process.send_after(
76+
self(),
77+
:load,
78+
polling_interval(state)
79+
)
80+
81+
%State{state | meta: new_nodelist}
82+
end
83+
84+
@spec get_nodes(State.t()) :: [atom()]
85+
defp get_nodes(%State{topology: topology, config: config}) do
86+
app_name = Keyword.fetch!(config, :application_name)
87+
service = Keyword.fetch!(config, :service)
88+
resolver = Keyword.get(config, :resolver, &:inet_res.getbyname(&1, :a))
89+
90+
IO.inspect(app_name, label: "Using application name ---------------------")
91+
IO.inspect(service, label: "Using service ---------------------")
92+
IO.inspect(resolver, label: "Using resolver ---------------------")
93+
IO.inspect(Node.get_cookie(), label: "Using node cookie ---------------------")
94+
95+
cond do
96+
app_name != nil and service != nil ->
97+
headless_service = to_charlist(service)
98+
99+
IO.inspect(headless_service, label: "Using headless service ---------------------")
100+
101+
case resolver.(headless_service) do
102+
{:ok, {:hostent, _fqdn, [], :inet, _value, addresses}} ->
103+
IO.inspect(addresses, label: "Using addresses ---------------------")
104+
parse_response(addresses, app_name)
105+
106+
{:error, reason} ->
107+
error(topology, "lookup against #{service} failed: #{inspect(reason)}")
108+
[]
109+
end
110+
111+
app_name == nil ->
112+
warn(
113+
topology,
114+
"kubernetes.DNS strategy is selected, but :application_name is not configured!"
115+
)
116+
117+
[]
118+
119+
service == nil ->
120+
warn(topology, "kubernetes strategy is selected, but :service is not configured!")
121+
[]
122+
123+
:else ->
124+
warn(topology, "kubernetes strategy is selected, but is not configured!")
125+
[]
126+
end
127+
end
128+
129+
defp polling_interval(%State{config: config}) do
130+
Keyword.get(config, :polling_interval, @default_polling_interval)
131+
end
132+
133+
defp parse_response(addresses, app_name) do
134+
addresses
135+
|> Enum.map(&:inet_parse.ntoa(&1))
136+
|> Enum.map(&"#{app_name}@#{&1}")
137+
|> Enum.map(&String.to_atom(&1))
138+
IO.inspect(&1, label: "Parsed addresses ---------------------")
139+
end
140+
end

lib/spawn/cluster/cluster_supervisor.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ defmodule Spawn.Cluster.ClusterSupervisor do
9494
defp get_k8s_dns_strategy(_opts),
9595
do: [
9696
proxy: [
97-
strategy: Elixir.Cluster.Strategy.Kubernetes.DNS,
97+
strategy: Elixir.Spawn.Cluster.ClusterResolver,
9898
config: [
9999
service: Config.get(:proxy_headless_service),
100100
application_name: Config.get(:actor_system_name),

spawn_operator/spawn_operator/lib/spawn_operator/k8s/proxy/deployment.ex

+30-30
Original file line numberDiff line numberDiff line change
@@ -276,22 +276,22 @@ defmodule SpawnOperator.K8s.Proxy.Deployment do
276276
actor_host_function_image = Map.get(host_params, "image")
277277

278278
updated_default_envs =
279-
[
280-
%{
281-
"name" => "RELEASE_NAME",
282-
"value" => system
283-
},
284-
%{
285-
"name" => "RELEASE_COOKIE",
286-
"valueFrom" => %{
287-
"secretKeyRef" => %{"name" => "#{system}-secret", "key" => "RELEASE_COOKIE"}
288-
}
289-
},
290-
%{
291-
"name" => "ERL_FLAGS",
292-
"value" => flags
279+
[
280+
%{
281+
"name" => "RELEASE_NAME",
282+
"value" => system
283+
},
284+
%{
285+
"name" => "RELEASE_COOKIE",
286+
"valueFrom" => %{
287+
"secretKeyRef" => %{"name" => "#{system}-secret", "key" => "RELEASE_COOKIE"}
293288
}
294-
] ++ @default_actor_host_function_env
289+
},
290+
%{
291+
"name" => "ERL_FLAGS",
292+
"value" => flags
293+
}
294+
] ++ @default_actor_host_function_env
295295

296296
actor_host_function_envs =
297297
if is_nil(task_actors_config) || List.first(Map.values(task_actors_config)) == %{} do
@@ -355,22 +355,22 @@ defmodule SpawnOperator.K8s.Proxy.Deployment do
355355
actor_host_function_image = Map.get(host_params, "image")
356356

357357
updated_default_envs =
358-
[
359-
%{
360-
"name" => "RELEASE_NAME",
361-
"value" => system
362-
},
363-
%{
364-
"name" => "RELEASE_COOKIE",
365-
"valueFrom" => %{
366-
"secretKeyRef" => %{"name" => "#{system}-secret", "key" => "RELEASE_COOKIE"}
367-
}
368-
},
369-
%{
370-
"name" => "ERL_FLAGS",
371-
"value" => flags
358+
[
359+
%{
360+
"name" => "RELEASE_NAME",
361+
"value" => system
362+
},
363+
%{
364+
"name" => "RELEASE_COOKIE",
365+
"valueFrom" => %{
366+
"secretKeyRef" => %{"name" => "#{system}-secret", "key" => "RELEASE_COOKIE"}
372367
}
373-
] ++ @default_actor_host_function_env
368+
},
369+
%{
370+
"name" => "ERL_FLAGS",
371+
"value" => flags
372+
}
373+
] ++ @default_actor_host_function_env
374374

375375
actor_host_function_envs =
376376
Map.get(host_params, "env", []) ++

0 commit comments

Comments
 (0)