couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject [couchdb] 01/01: Pre-calculate application start order
Date Tue, 16 May 2017 19:32:22 GMT
This is an automated email from the ASF dual-hosted git repository.

davisp pushed a commit to branch start-app-order
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 0803f2597ccfd139ec71863292e9b461a9b3d030
Author: Paul J. Davis <paul.joseph.davis@gmail.com>
AuthorDate: Tue May 16 11:12:24 2017 -0500

    Pre-calculate application start order
    
    This allows us to make some better assertions/logging when starting our
    application list on what should and should not already be started.
---
 src/couch/src/test_util.erl | 62 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/src/couch/src/test_util.erl b/src/couch/src/test_util.erl
index 3c4d170..aa94542 100644
--- a/src/couch/src/test_util.erl
+++ b/src/couch/src/test_util.erl
@@ -83,23 +83,26 @@ stop_couch(_) ->
     stop_couch().
 
 start_applications(Apps) ->
-    start_applications(Apps, []).
+    StartOrder = calculate_start_order(Apps),
+    io:format(standard_error, "STARTING: ~p~n", [StartOrder]),
+    start_applications(StartOrder, []).
 
 start_applications([], Acc) ->
     lists:reverse(Acc);
+start_applications([App|Apps], Acc) when App == kernel; App == stdlib ->
+    start_applications(Apps, Acc);
 start_applications([App|Apps], Acc) ->
     case application:start(App) of
-    {error, {already_started, _}} ->
-        start_applications(Apps, Acc);
-    {error, {not_started, Dep}} ->
-        start_applications([Dep, App | Apps], Acc);
-    {error, {not_running, Dep}} ->
-        start_applications([Dep, App | Apps], Acc);
+    {error, {already_started, App}} ->
+        io:format(standard_error, "Application ~s was left running!~n", [App]),
+        application:stop(App),
+        start_applications([App|Apps], Acc);
     ok ->
         start_applications(Apps, [App|Acc])
     end.
 
 stop_applications(Apps) ->
+    io:format(standard_error, "STOPPING: ~p~n", [Apps]),
     [application:stop(App) || App <- lists:reverse(Apps)],
     ok.
 
@@ -258,3 +261,48 @@ load_applications_with_stats() ->
 stats_file_to_app(File) ->
     [_Desc, _Priv, App|_] = lists:reverse(filename:split(File)),
     erlang:list_to_atom(App).
+
+calculate_start_order(Apps) ->
+    AllApps = calculate_start_order(sort_apps(Apps), []),
+    % AllApps may not be the same list as Apps if we
+    % loaded any dependencies. We recurse here when
+    % that changes so that our sort_apps function has
+    % a global view of all applications to start.
+    case lists:usort(AllApps) == lists:usort(Apps) of
+        true -> AllApps;
+        false -> calculate_start_order(AllApps)
+    end.
+
+calculate_start_order([], StartOrder) ->
+    lists:reverse(StartOrder);
+calculate_start_order([App | RestApps], StartOrder) ->
+    NewStartOrder = load_app_deps(App, StartOrder),
+    calculate_start_order(RestApps, NewStartOrder).
+
+load_app_deps(App, StartOrder) ->
+    case lists:member(App, StartOrder) of
+        true ->
+            StartOrder;
+        false ->
+            case application:load(App) of
+                ok -> ok;
+                {error, {already_loaded, App}} -> ok
+            end,
+            {ok, Apps} = application:get_key(App, applications),
+            Deps = case App of
+                kernel -> Apps;
+                stdlib -> Apps;
+                _ -> lists:usort([kernel, stdlib | Apps])
+            end,
+            NewStartOrder = lists:foldl(fun(Dep, Acc) ->
+                load_app_deps(Dep, Acc)
+            end, StartOrder, Deps),
+            [App | NewStartOrder]
+    end.
+
+sort_apps(Apps) ->
+    Weighted = [weight_app(App) || App <- Apps],
+    element(2, lists:unzip(lists:sort(Weighted))).
+
+weight_app(couch_log) -> {0.0, couch_log};
+weight_app(Else) -> {1.0, Else}.

-- 
To stop receiving notification emails like this one, please contact
"commits@couchdb.apache.org" <commits@couchdb.apache.org>.

Mime
View raw message