Skip to content

Commit c95dda0

Browse files
committedMar 22, 2023
Explicitly remove delegate from its supervisor on name conflict
1 parent 4e4661a commit c95dda0

File tree

6 files changed

+68
-14
lines changed

6 files changed

+68
-14
lines changed
 

‎config/config.exs

+6
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@ import Config
22

33
if Mix.env() == :test do
44
config :logger, level: :warn
5+
6+
# config :logger,
7+
# format: "$message\n",
8+
# level: String.to_atom(System.get_env("LOG_LEVEL") || "info"),
9+
# handle_otp_reports: true,
10+
# handle_sasl_reports: true
511
end

‎lib/sworm/delegate.ex

+3-2
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ defmodule Sworm.Delegate do
114114
{:stop, :shutdown, state}
115115
end
116116

117-
def handle_info({:EXIT, _, {:name_conflict, {_name, _}, _reg, _winner} = r}, state) do
118-
{:stop, r, state}
117+
def handle_info({:EXIT, _, {:name_conflict, {_name, _}, _reg, _winner}}, state) do
118+
Horde.DynamicSupervisor.terminate_child(supervisor_name(state.sworm), self())
119+
{:stop, :normal, state}
119120
end
120121

121122
def handle_info({:EXIT, _, reason}, state) do

‎mix.lock

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
"delta_crdt": {:hex, :delta_crdt, "0.5.10", "e866f8d1b89bee497a98b9793e9ba0ea514112a1c41a0c30dcde3463d4984d14", [:mix], [{:merkle_map, "~> 0.2.0", [hex: :merkle_map, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ed5c685df9528788d7c056762c23f75358f3cadd4779698188a55ccae24d087a"},
33
"dialyxir": {:hex, :dialyxir, "1.0.0-rc.7", "6287f8f2cb45df8584317a4be1075b8c9b8a69de8eeb82b4d9e6c761cf2664cd", [:mix], [{:erlex, ">= 0.2.5", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "506294d6c543e4e5282d4852aead19ace8a35bedeb043f9256a06a6336827122"},
44
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
5+
"earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"},
56
"erlex": {:hex, :erlex, "0.2.5", "e51132f2f472e13d606d808f0574508eeea2030d487fc002b46ad97e738b0510", [:mix], [], "hexpm", "756d3e19b056339af674b715fdd752c5dac468cf9d0e2d1a03abf4574e99fbf8"},
6-
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f1155337ae17ff7a1255217b4c1ceefcd1860b7ceb1a1874031e7a861b052e39"},
7+
"ex_doc": {:hex, :ex_doc, "0.29.3", "f07444bcafb302db86e4f02d8bbcd82f2e881a0dcf4f3e4740e4b8128b9353f7", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3dc6787d7b08801ec3b51e9bd26be5e8826fbf1a17e92d1ebc252e1a1c75bfe1"},
78
"ex_unit_clustered_case": {:git, "https://github.com/bitwalker/ex_unit_clustered_case.git", "7762c0a0cce1c78703a1955ce9bc89c0ff9d2f88", []},
89
"horde": {:hex, :horde, "0.7.1", "161e140e4e4fab5416b90a4e5b68fbe7fb78f62b265f87f01d661a58aa72be0c", [:mix], [{:delta_crdt, "~> 0.5.10", [hex: :delta_crdt, repo: "hexpm", optional: false]}, {:libring, "~> 1.4", [hex: :libring, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_poller, "~> 0.4.0", [hex: :telemetry_poller, repo: "hexpm", optional: false]}], "hexpm", "cbf5416cd4d221be07420d40a575cdaa1300a03d7ef593f805705e6b54f6187c"},
910
"libring": {:hex, :libring, "1.6.0", "d5dca4bcb1765f862ab59f175b403e356dec493f565670e0bacc4b35e109ce0d", [:mix], [], "hexpm", "5e91ece396af4bce99953d49ee0b02f698cd38326d93cd068361038167484319"},
10-
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"},
11-
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
11+
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
12+
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
13+
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
1214
"merkle_map": {:hex, :merkle_map, "0.2.0", "5391ac61e016ce4aeb66ce39f05206a382fd4b66ee4b63c08a261d5633eadd76", [:mix], [], "hexpm", "fb1cc3a80e0b0d439a83bdb42bde4d03e8970a436bc949b9fa8d951c18fdafde"},
13-
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
15+
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
1416
"telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"},
1517
"telemetry_poller": {:hex, :telemetry_poller, "0.4.1", "50d03d976a3b8ab4898d9e873852e688840df47685a13af90af40e1ba43a758b", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c5bacbbcd62c1fe4e4517485bd64312622e9b83683273dcf2627ff224d7d485b"},
1618
}

‎test/cluster_test.exs

+39-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ defmodule SwormClusterTest do
5151
# settle
5252
wait_until(fn ->
5353
match?(
54-
[[{"hi", _}], [{"hi", _}]],
54+
[[{"hi", p}], [{"hi", p}]],
5555
Cluster.members(c) |> Enum.map(fn n -> Cluster.call(n, Swurm, :registered, []) end)
5656
)
5757
end)
@@ -180,4 +180,42 @@ defmodule SwormClusterTest do
180180
until_match([_], Cluster.call(a, Sworm.DirectoryManager, :nodes_for_sworm, [Swurm]))
181181
end
182182
end
183+
184+
require Logger
185+
186+
sworm_scenario Swurm, "given a partitioned cluster" do
187+
test "resolves name conflicts", %{cluster: c} do
188+
[a, b] = Cluster.members(c)
189+
Cluster.partition(c, [[a], [b]])
190+
191+
assert {:ok, pid_a} = Cluster.call(a, Swurm, :start_one, ["hi"])
192+
assert {:ok, pid_b} = Cluster.call(b, Swurm, :start_one, ["hi"])
193+
194+
assert pid_a != pid_b
195+
196+
Process.sleep(500)
197+
198+
Cluster.heal(c)
199+
200+
wait_until(fn ->
201+
case {Cluster.call(a, Swurm, :registered, []), Cluster.call(b, Swurm, :registered, [])} do
202+
{[{"hi", pid}], [{"hi", pid}]} ->
203+
true
204+
205+
_ ->
206+
false
207+
end
208+
end)
209+
210+
# we now have only one pid
211+
[{"hi", pid}] = Cluster.call(a, Swurm, :registered, [])
212+
[{"hi", ^pid}] = Cluster.call(b, Swurm, :registered, [])
213+
214+
# stop it before exiting
215+
GenServer.stop(pid)
216+
217+
until_match([], Cluster.call(a, Swurm, :registered, []))
218+
until_match([], Cluster.call(b, Swurm, :registered, []))
219+
end
220+
end
183221
end

‎test/support/helpers.ex

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ defmodule Sworm.Support.Helpers do
1717
Process.unlink(pid)
1818

1919
mod ->
20-
{:ok, pid} = mod.start_link()
20+
opts = [delta_crdt_options: [sync_interval: 50]]
21+
{:ok, pid} = mod.start_link(opts)
2122
Process.unlink(pid)
2223
end
2324

‎test/sworm_test.exs

+12-6
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ defmodule SwormTest do
1313
defmodule TestServer do
1414
use GenServer
1515

16-
def start_link() do
17-
GenServer.start_link(__MODULE__, [])
16+
def start_link(arg \\ []) do
17+
GenServer.start_link(__MODULE__, arg)
1818
end
1919

20-
def init([]), do: {:ok, nil}
20+
def init(_arg) do
21+
{:ok, nil}
22+
end
2123

2224
def handle_call(:x, _from, state) do
2325
{:reply, :y, state}
@@ -117,16 +119,18 @@ defmodule SwormTest do
117119
assert [_] = delegates()
118120
end
119121

122+
require Logger
123+
120124
test "remove from supervisor on name conflict" do
121125
# Simulate a network partition healing, 2 processes registered on
122126
# different nodes are reconciled.
123127

124128
sworm(A)
125129
sworm(B)
126130

127-
assert {:ok, pid_a} = Sworm.register_name(A, "foo", TestServer, :start_link, [])
131+
assert {:ok, pid_a} = Sworm.register_name(A, "foo", TestServer, :start_link, ["foo.A"])
128132
Process.sleep(10)
129-
assert {:ok, pid_b} = Sworm.register_name(B, "foo", TestServer, :start_link, [])
133+
assert {:ok, pid_b} = Sworm.register_name(B, "foo", TestServer, :start_link, ["foo.B"])
130134

131135
Horde.Cluster.set_members(A.Registry, [A.Registry, B.Registry])
132136
Horde.Cluster.set_members(A.Supervisor, [A.Supervisor, B.Supervisor])
@@ -139,11 +143,13 @@ defmodule SwormTest do
139143
assert([{"foo", ^pid_b}] = Sworm.registered(A))
140144
assert([{"foo", ^pid_b}] = Sworm.registered(B))
141145

146+
# removed from A.Supervisor
142147
until_match(
143-
[{:undefined, _delegate, _, _}],
148+
[],
144149
Horde.DynamicSupervisor.which_children(A.Supervisor)
145150
)
146151

152+
# still exists on B.Supervisor
147153
until_match(
148154
[{:undefined, _delegate, _, _}],
149155
Horde.DynamicSupervisor.which_children(B.Supervisor)

0 commit comments

Comments
 (0)
Please sign in to comment.