Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 56 lines (44 sloc) 2.532 kb
44a5bb4 @jlouis Hint Emacs that the Tab Stop of the files are 4 spaces.
jlouis authored
1 %% -*- Mode: Erlang; tab-width: 4 -*-
1aabca9 @yrashk Initial WIP, nothing to see yet
yrashk authored
2 -module(agner_app).
3
4 -behaviour(application).
5
6 %% Application callbacks
db2527c @yrashk agner_repo_servers cleanup after themselves properly now
yrashk authored
7 -export([start/2, stop/1, prep_stop/1]).
1aabca9 @yrashk Initial WIP, nothing to see yet
yrashk authored
8
9 %% ===================================================================
10 %% Application callbacks
11 %% ===================================================================
12
13 start(_StartType, _StartArgs) ->
db2527c @yrashk agner_repo_servers cleanup after themselves properly now
yrashk authored
14 {ok, Pid} = agner_sup:start_link(),
15 {ok, Pid, []}.
1aabca9 @yrashk Initial WIP, nothing to see yet
yrashk authored
16
db2527c @yrashk agner_repo_servers cleanup after themselves properly now
yrashk authored
17 %% The reason for the code below is that we have a simple_one_for_one supervisor
18 %% (agner_repo_server_sup) and according to supervisor's documentation:
19 %% "Important note on simple-one-for-one supervisors: The dynamically created child
20 %% processes of a simple-one-for-one supervisor are not explicitly killed, regardless of
21 %% shutdown strategy, but are expected to terminate when the supervisor does (that is, when
22 %% an exit signal from the parent process is received)."
23 %% Since agner_repo_server is actually trapping exits to run terminate/2 to clean up
24 %% after itself, some (sometimes may be all of them) of its instances *do* receive an EXIT
25 %% from the supervisor and get their terminate/2 callbacks called; but since the supervisor
26 %% is not explicitly killing them and not waiting for them to die, it means by the time
27 %% supervisor is dead, some of them *may have* went through terminate/2 and some may have not,
28 %% but since the top supervisor was wrapping up its business and dying as well, the application
29 %% master (as a group leader) was going through killing all remaining children regardless of whether
30 %% they finished their business or not (and by business we mean terminate/2 here), and thus
31 %% preventing their proper cleanup.
32
33 %% So what we are doing here is we're memorizing the list of children that are about to terminate
34 %% in prep_stop/1 and put them into the application state, and once top supervisor is dead and
35 %% stop/1 is called, we pick them up from the state, setup monitors on them and wait until every
36 %% one of them is DOWN (and that means the stuff is now cleaned up)
37
0e70cf4 @yrashk Minor typo fix
yrashk authored
38 %% This would probably take a whole lot more time to figure out if Fred Hebert hadn't offered
db2527c @yrashk agner_repo_servers cleanup after themselves properly now
yrashk authored
39 %% his help to brainstorm this problem through. Merci pour l'aide!
40
41
42 prep_stop(_) ->
43 lists:map(fun ({_,P,_,_}) -> P end, supervisor:which_children(agner_repo_server_sup)).
44
45 stop(State) ->
46 stop_loop(lists:map(fun (P) -> monitor(process, P) end, State)),
1aabca9 @yrashk Initial WIP, nothing to see yet
yrashk authored
47 ok.
db2527c @yrashk agner_repo_servers cleanup after themselves properly now
yrashk authored
48
49 stop_loop([]) ->
50 ok;
51 stop_loop([Ref|Rest]) ->
52 receive
53 {'DOWN',Ref,process,_,_} ->
54 stop_loop(Rest)
55 end.
Something went wrong with that request. Please try again.