summaryrefslogtreecommitdiff
path: root/src/rabbit_upgrade.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rabbit_upgrade.erl')
-rw-r--r--src/rabbit_upgrade.erl64
1 files changed, 35 insertions, 29 deletions
diff --git a/src/rabbit_upgrade.erl b/src/rabbit_upgrade.erl
index 9522227e..27a94f6f 100644
--- a/src/rabbit_upgrade.erl
+++ b/src/rabbit_upgrade.erl
@@ -32,11 +32,13 @@
-ifdef(use_specs).
+-type(step() :: atom()).
+-type(version() :: [step()]).
+
-spec(maybe_upgrade/0 :: () -> 'ok' | 'version_not_available').
--spec(read_version/0 ::
- () -> {'ok', [any()]} | rabbit_types:error(any())).
+-spec(read_version/0 :: () -> rabbit_types:ok_or_error2(version(), any())).
-spec(write_version/0 :: () -> 'ok').
--spec(desired_version/0 :: () -> [atom()]).
+-spec(desired_version/0 :: () -> version()).
-endif.
@@ -48,18 +50,17 @@
maybe_upgrade() ->
case read_version() of
{ok, CurrentHeads} ->
- G = load_graph(),
- case unknown_heads(CurrentHeads, G) of
- [] ->
- case upgrades_to_apply(CurrentHeads, G) of
- [] -> ok;
- Upgrades -> apply_upgrades(Upgrades)
- end;
- Unknown ->
- exit({future_upgrades_found, Unknown})
- end,
- true = digraph:delete(G),
- ok;
+ with_upgrade_graph(
+ fun (G) ->
+ case unknown_heads(CurrentHeads, G) of
+ [] -> case upgrades_to_apply(CurrentHeads, G) of
+ [] -> ok;
+ Upgrades -> apply_upgrades(Upgrades)
+ end;
+ Unknown -> throw({error,
+ {future_upgrades_found, Unknown}})
+ end
+ end);
{error, enoent} ->
version_not_available
end.
@@ -75,17 +76,26 @@ write_version() ->
ok.
desired_version() ->
- G = load_graph(),
- Version = heads(G),
- true = digraph:delete(G),
- Version.
+ with_upgrade_graph(fun (G) -> heads(G) end).
%% -------------------------------------------------------------------
-load_graph() ->
- Upgrades = rabbit_misc:all_module_attributes(rabbit_upgrade),
- rabbit_misc:build_acyclic_graph(
- fun vertices/2, fun edges/2, fun graph_build_error/1, Upgrades).
+with_upgrade_graph(Fun) ->
+ case rabbit_misc:build_acyclic_graph(
+ fun vertices/2, fun edges/2,
+ rabbit_misc:all_module_attributes(rabbit_upgrade)) of
+ {ok, G} -> try
+ Fun(G)
+ after
+ true = digraph:delete(G)
+ end;
+ {error, {vertex, duplicate, StepName}} ->
+ throw({error, {duplicate_upgrade_step, StepName}});
+ {error, {edge, {bad_vertex, StepName}, _From, _To}} ->
+ throw({error, {dependency_on_unknown_upgrade_step, StepName}});
+ {error, {edge, {bad_edge, StepNames}, _From, _To}} ->
+ throw({error, {cycle_in_upgrade_steps, StepNames}})
+ end.
vertices(Module, Steps) ->
[{StepName, {Module, StepName}} || {StepName, _Reqs} <- Steps].
@@ -93,10 +103,6 @@ vertices(Module, Steps) ->
edges(_Module, Steps) ->
[{Require, StepName} || {StepName, Requires} <- Steps, Require <- Requires].
-graph_build_error({vertex, duplicate, StepName}) ->
- exit({duplicate_upgrade, StepName});
-graph_build_error({edge, E, From, To}) ->
- exit({E, From, To}).
unknown_heads(Heads, G) ->
[H || H <- Heads, digraph:vertex(G, H) =:= false].
@@ -130,9 +136,9 @@ apply_upgrades(Upgrades) ->
ok = write_version(),
ok = file:delete(LockFile);
{error, eexist} ->
- exit(previous_upgrade_failed);
+ throw({error, previous_upgrade_failed});
{error, _} = Error ->
- exit(Error)
+ throw(Error)
end.
apply_upgrade({M, F}) ->