diff options
Diffstat (limited to 'src/rabbit_upgrade.erl')
-rw-r--r-- | src/rabbit_upgrade.erl | 64 |
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}) -> |