diff options
author | Simon MacMullen <simon@rabbitmq.com> | 2014-06-09 15:37:35 +0100 |
---|---|---|
committer | Simon MacMullen <simon@rabbitmq.com> | 2014-06-09 15:37:35 +0100 |
commit | 60096a3faff2228b616c408477bd9ff6df9db9e6 (patch) | |
tree | 31b929152ec310429fe74b7b799129a8276f66e5 | |
parent | a76f071596d22abe6aa0190bb234a5d90b2199b3 (diff) | |
download | rabbitmq-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.erl | 2 | ||||
-rw-r--r-- | src/rabbit_exchange.erl | 55 |
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. |