diff options
| author | Daniil Fedotov <hairyhum@gmail.com> | 2019-02-14 15:48:07 -0500 |
|---|---|---|
| committer | Daniil Fedotov <hairyhum@gmail.com> | 2019-02-14 15:51:29 -0500 |
| commit | 13985a751795184c75b150a9dfbca48becdcdfd6 (patch) | |
| tree | 5d29d95f912d6213bdc803059ad3971ee3f29dd5 | |
| parent | bdf3cfb76205fef2b6208b17cc81f3b86d8b1db6 (diff) | |
| download | rabbitmq-server-git-13985a751795184c75b150a9dfbca48becdcdfd6.tar.gz | |
Do not fail on bind/unbind operations if the binding records are inconsistent.
If there is a record for the rabbit_durable_route table but no record
for rabbit_route table, the binding operations should still proceed to
create/remove bindings. This will allow the clients to fix data inconsistency
that server did not fix during recovery.
[#163952284]
| -rw-r--r-- | src/rabbit_binding.erl | 28 | ||||
| -rw-r--r-- | src/rabbit_channel.erl | 5 |
2 files changed, 13 insertions, 20 deletions
diff --git a/src/rabbit_binding.erl b/src/rabbit_binding.erl index ab3bc6c819..daa0d1b817 100644 --- a/src/rabbit_binding.erl +++ b/src/rabbit_binding.erl @@ -49,7 +49,6 @@ -type bind_ok_or_error() :: 'ok' | bind_errors() | rabbit_types:error( - 'binding_not_found' | {'binding_invalid', string(), [any()]}). -type bind_res() :: bind_ok_or_error() | rabbit_misc:thunk(bind_ok_or_error()). -type inner_fun() :: @@ -178,19 +177,15 @@ add(Src, Dst, B, ActingUser) -> lock_resource(Src), lock_resource(Dst), [SrcDurable, DstDurable] = [durable(E) || E <- [Src, Dst]], - case (SrcDurable andalso DstDurable andalso - mnesia:read({rabbit_durable_route, B}) =/= []) of - false -> ok = sync_route(#route{binding = B}, SrcDurable, DstDurable, - fun mnesia:write/3), - x_callback(transaction, Src, add_binding, B), - Serial = rabbit_exchange:serial(Src), - fun () -> - x_callback(Serial, Src, add_binding, B), - ok = rabbit_event:notify( - binding_created, - info(B) ++ [{user_who_performed_action, ActingUser}]) - end; - true -> rabbit_misc:const({error, binding_not_found}) + ok = sync_route(#route{binding = B}, SrcDurable, DstDurable, + fun mnesia:write/3), + x_callback(transaction, Src, add_binding, B), + Serial = rabbit_exchange:serial(Src), + fun () -> + x_callback(Serial, Src, add_binding, B), + ok = rabbit_event:notify( + binding_created, + info(B) ++ [{user_who_performed_action, ActingUser}]) end. -spec remove(rabbit_types:binding()) -> bind_res(). @@ -208,7 +203,10 @@ remove(Binding, InnerFun, ActingUser) -> case mnesia:read(rabbit_route, B, write) of [] -> case mnesia:read(rabbit_durable_route, B, write) of [] -> rabbit_misc:const(ok); - _ -> rabbit_misc:const({error, binding_not_found}) + %% We still delete the binding and run + %% all post-delete functions if there is only + %% a durable route in the database + _ -> remove(Src, Dst, B, ActingUser) end; _ -> case InnerFun(Src, Dst) of ok -> remove(Src, Dst, B, ActingUser); diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl index 036aa9a60c..ada037925b 100644 --- a/src/rabbit_channel.erl +++ b/src/rabbit_channel.erl @@ -1845,11 +1845,6 @@ binding_action(Fun, SourceNameBin0, DestinationType, DestinationNameBin0, rabbit_amqqueue:not_found(Name); {error, {resources_missing, [{absent, Q, Reason} | _]}} -> rabbit_amqqueue:absent(Q, Reason); - {error, binding_not_found} -> - rabbit_misc:protocol_error( - not_found, "no binding ~s between ~s and ~s", - [RoutingKey, rabbit_misc:rs(ExchangeName), - rabbit_misc:rs(DestinationName)]); {error, {binding_invalid, Fmt, Args}} -> rabbit_misc:protocol_error(precondition_failed, Fmt, Args); {error, #amqp_error{} = Error} -> |
