@@ -83,18 +83,19 @@ stop_couch(_) ->
8383 stop_couch ().
8484
8585start_applications (Apps ) ->
86- start_applications (Apps , []).
86+ StartOrder = calculate_start_order (Apps ),
87+ start_applications (StartOrder , []).
8788
8889start_applications ([], Acc ) ->
8990 lists :reverse (Acc );
91+ start_applications ([App |Apps ], Acc ) when App == kernel ; App == stdlib ->
92+ start_applications (Apps , Acc );
9093start_applications ([App |Apps ], Acc ) ->
9194 case application :start (App ) of
92- {error , {already_started , _ }} ->
93- start_applications (Apps , Acc );
94- {error , {not_started , Dep }} ->
95- start_applications ([Dep , App | Apps ], Acc );
96- {error , {not_running , Dep }} ->
97- start_applications ([Dep , App | Apps ], Acc );
95+ {error , {already_started , App }} ->
96+ io :format (standard_error , " Application ~s was left running!~n " , [App ]),
97+ application :stop (App ),
98+ start_applications ([App |Apps ], Acc );
9899 ok ->
99100 start_applications (Apps , [App |Acc ])
100101 end .
@@ -258,3 +259,48 @@ load_applications_with_stats() ->
258259stats_file_to_app (File ) ->
259260 [_Desc , _Priv , App |_ ] = lists :reverse (filename :split (File )),
260261 erlang :list_to_atom (App ).
262+
263+ calculate_start_order (Apps ) ->
264+ AllApps = calculate_start_order (sort_apps (Apps ), []),
265+ % AllApps may not be the same list as Apps if we
266+ % loaded any dependencies. We recurse here when
267+ % that changes so that our sort_apps function has
268+ % a global view of all applications to start.
269+ case lists :usort (AllApps ) == lists :usort (Apps ) of
270+ true -> AllApps ;
271+ false -> calculate_start_order (AllApps )
272+ end .
273+
274+ calculate_start_order ([], StartOrder ) ->
275+ lists :reverse (StartOrder );
276+ calculate_start_order ([App | RestApps ], StartOrder ) ->
277+ NewStartOrder = load_app_deps (App , StartOrder ),
278+ calculate_start_order (RestApps , NewStartOrder ).
279+
280+ load_app_deps (App , StartOrder ) ->
281+ case lists :member (App , StartOrder ) of
282+ true ->
283+ StartOrder ;
284+ false ->
285+ case application :load (App ) of
286+ ok -> ok ;
287+ {error , {already_loaded , App }} -> ok
288+ end ,
289+ {ok , Apps } = application :get_key (App , applications ),
290+ Deps = case App of
291+ kernel -> Apps ;
292+ stdlib -> Apps ;
293+ _ -> lists :usort ([kernel , stdlib | Apps ])
294+ end ,
295+ NewStartOrder = lists :foldl (fun (Dep , Acc ) ->
296+ load_app_deps (Dep , Acc )
297+ end , StartOrder , Deps ),
298+ [App | NewStartOrder ]
299+ end .
300+
301+ sort_apps (Apps ) ->
302+ Weighted = [weight_app (App ) || App <- Apps ],
303+ element (2 , lists :unzip (lists :sort (Weighted ))).
304+
305+ weight_app (couch_log ) -> {0.0 , couch_log };
306+ weight_app (Else ) -> {1.0 , Else }.
0 commit comments