summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2014-06-09 15:37:35 +0100
committerSimon MacMullen <simon@rabbitmq.com>2014-06-09 15:37:35 +0100
commit60096a3faff2228b616c408477bd9ff6df9db9e6 (patch)
tree31b929152ec310429fe74b7b799129a8276f66e5
parenta76f071596d22abe6aa0190bb234a5d90b2199b3 (diff)
downloadrabbitmq-server-bug26230.tar.gz
Ensure rabbit_exchange funnels all updates through a single function, like rabbit_amqqueue already does. Ensure that decorators is set to 'undefined' in the durable record so any inadvertent read without setting it will cause an immediate explosion not a subtle bug. And remove report_missing_decorators(), there is no longer any sane context in which it does anything useful.bug26230
-rw-r--r--src/rabbit_amqqueue.erl2
-rw-r--r--src/rabbit_exchange.erl55
2 files changed, 23 insertions, 34 deletions
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl
index 8bc0cab6..b0b78257 100644
--- a/src/rabbit_amqqueue.erl
+++ b/src/rabbit_amqqueue.erl
@@ -310,7 +310,7 @@ store_queue(Q = #amqqueue{durable = true}) ->
Q#amqqueue{slave_pids = [],
sync_slave_pids = [],
gm_pids = [],
- decorators = []}, write),
+ decorators = undefined}, write),
store_queue0(Q);
store_queue(Q = #amqqueue{durable = false}) ->
store_queue0(Q).
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index f1b2d694..350de2a8 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -106,24 +106,15 @@ recover() ->
mnesia:read({rabbit_exchange, XName}) =:= []
end,
fun (X, Tx) ->
- case Tx of
- true -> store(X);
- false -> ok
- end,
- callback(X, create, map_create_tx(Tx), [X])
+ X1 = case Tx of
+ true -> store0(X);
+ false -> rabbit_exchange_decorator:set(X)
+ end,
+ callback(X1, create, map_create_tx(Tx), [X1])
end,
rabbit_durable_exchange),
- report_missing_decorators(Xs),
[XName || #exchange{name = XName} <- Xs].
-report_missing_decorators(Xs) ->
- Mods = lists:usort(lists:append([rabbit_exchange_decorator:select(raw, D) ||
- #exchange{decorators = D} <- Xs])),
- case [M || M <- Mods, code:which(M) =:= non_existing] of
- [] -> ok;
- M -> rabbit_log:warning("Missing exchange decorators: ~p~n", [M])
- end.
-
callback(X = #exchange{type = XType,
decorators = Decorators}, Fun, Serial0, Args) ->
Serial = if is_function(Serial0) -> Serial0;
@@ -172,13 +163,7 @@ declare(XName, Type, Durable, AutoDelete, Internal, Args) ->
fun () ->
case mnesia:wread({rabbit_exchange, XName}) of
[] ->
- store(X),
- ok = case Durable of
- true -> mnesia:write(rabbit_durable_exchange,
- X, write);
- false -> ok
- end,
- {new, X};
+ {new, store(X)};
[ExistingX] ->
{existing, ExistingX}
end
@@ -196,8 +181,19 @@ declare(XName, Type, Durable, AutoDelete, Internal, Args) ->
map_create_tx(true) -> transaction;
map_create_tx(false) -> none.
-store(X) -> ok = mnesia:write(
- rabbit_exchange, rabbit_exchange_decorator:set(X), write).
+
+store(X = #exchange{durable = true}) ->
+ mnesia:write(rabbit_durable_exchange, X#exchange{decorators = undefined},
+ write),
+ store0(X);
+store(X = #exchange{durable = false}) ->
+ store0(X).
+
+store0(X) ->
+ X1 = rabbit_exchange_decorator:set(X),
+ ok = mnesia:write(rabbit_exchange, rabbit_exchange_decorator:set(X1),
+ write),
+ X1.
%% Used with binaries sent over the wire; the type may not exist.
check_type(TypeBin) ->
@@ -291,16 +287,9 @@ update_scratch(Name, App, Fun) ->
update(Name, Fun) ->
case mnesia:wread({rabbit_exchange, Name}) of
- [X = #exchange{durable = Durable}] ->
- X1 = Fun(X),
- ok = mnesia:write(rabbit_exchange, X1, write),
- case Durable of
- true -> ok = mnesia:write(rabbit_durable_exchange, X1, write);
- _ -> ok
- end,
- X1;
- [] ->
- not_found
+ [X] -> X1 = Fun(X),
+ store(X1);
+ [] -> not_found
end.
info_keys() -> ?INFO_KEYS.