Skip to content

Commit 127c25a

Browse files
committed
fix: ensure cleanup after shutdown
1 parent 392237d commit 127c25a

3 files changed

Lines changed: 29 additions & 2 deletions

File tree

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* 4.1.3
2+
- Ensure `wolff_client_sup:ensure_absence` and `wolff_producers_sup:ensure_absence` will perform shutdown and cleanup atomically.
3+
Previously, if the caller process is killed while waiting for shutdown, a terminated child may leak under the supervisor.
4+
15
* 4.1.2
26
- Made sure `wolff_client:check_topic_exists_with_client_pid/2` triggers topic creation when `allow_auto_topic_creation` is set to `true`.
37

src/wolff_client_sup.erl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ ensure_present(ClientId, Hosts, Config) ->
5050
%% @doc Ensure client stopped and deleted under supervisor.
5151
-spec ensure_absence(wolff:client_id()) -> ok.
5252
ensure_absence(ClientId) ->
53+
%% This receive may take 5s because the child spec's shutdown policy is to kill after 5s
54+
%% To ensure the cleanup is complete, spawn a process to do it, in case the caller
55+
%% gets killed while waiting for shutdown.
56+
{Pid, Mref} = erlang:spawn_monitor(fun() -> do_ensure_absence(ClientId) end),
57+
receive
58+
{'DOWN', Mref, process, Pid, _} ->
59+
ok
60+
end.
61+
62+
do_ensure_absence(ClientId) ->
5363
case supervisor:terminate_child(?SUPERVISOR, ClientId) of
5464
ok -> ok = supervisor:delete_child(?SUPERVISOR, ClientId);
5565
{error, not_found} -> ok
@@ -79,7 +89,8 @@ child_spec(ClientId, Hosts, Config) ->
7989
start => {wolff_client, start_link, [ClientId, Hosts, Config]},
8090
restart => transient,
8191
type => worker,
82-
modules => [wolff_client]
92+
modules => [wolff_client],
93+
shutdown => 5000
8394
}.
8495

8596
%% @doc Create a ets table which is used for client registration.

src/wolff_producers_sup.erl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ ensure_present(ClientId, ProducerId, Config) ->
4848
%% ensure client stopped and deleted under supervisor
4949
-spec ensure_absence(wolff_producers:id()) -> ok.
5050
ensure_absence(ProducerId) ->
51+
%% This receive may take 5s because the child spec's shutdown policy is to kill after 5s
52+
%% To ensure the cleanup is complete, spawn a process to do it, in case the caller
53+
%% gets killed while waiting for shutdown.
54+
{Pid, Mref} = erlang:spawn_monitor(fun() -> do_ensure_absence(ProducerId) end),
55+
receive
56+
{'DOWN', Mref, process, Pid, _} ->
57+
ok
58+
end.
59+
60+
do_ensure_absence(ProducerId) ->
5161
case supervisor:terminate_child(?SUPERVISOR, ProducerId) of
5262
ok ->
5363
ok = wolff_producers:cleanup_workers_table(ProducerId),
@@ -60,7 +70,9 @@ child_spec(ClientId, ProducerId, Config) ->
6070
#{id => ProducerId,
6171
start => {wolff_producers, start_link, [ClientId, ProducerId, Config]},
6272
restart => transient,
63-
type => worker
73+
type => worker,
74+
modules => [wolff_producers],
75+
shutdown => 5000
6476
}.
6577

6678
%% Find the running process (gen_server of wolff_producers) from thie child ID.

0 commit comments

Comments
 (0)