Skip to content

Commit 2f1b24e

Browse files
hairyhumkjnilsson
authored andcommitted
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]
1 parent fb1a043 commit 2f1b24e

File tree

2 files changed

+13
-20
lines changed

2 files changed

+13
-20
lines changed

src/rabbit_binding.erl

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949

5050
-type bind_ok_or_error() :: 'ok' | bind_errors() |
5151
rabbit_types:error(
52-
'binding_not_found' |
5352
{'binding_invalid', string(), [any()]}).
5453
-type bind_res() :: bind_ok_or_error() | rabbit_misc:thunk(bind_ok_or_error()).
5554
-type inner_fun() ::
@@ -178,19 +177,15 @@ add(Src, Dst, B, ActingUser) ->
178177
lock_resource(Src),
179178
lock_resource(Dst),
180179
[SrcDurable, DstDurable] = [durable(E) || E <- [Src, Dst]],
181-
case (SrcDurable andalso DstDurable andalso
182-
mnesia:read({rabbit_durable_route, B}) =/= []) of
183-
false -> ok = sync_route(#route{binding = B}, SrcDurable, DstDurable,
184-
fun mnesia:write/3),
185-
x_callback(transaction, Src, add_binding, B),
186-
Serial = rabbit_exchange:serial(Src),
187-
fun () ->
188-
x_callback(Serial, Src, add_binding, B),
189-
ok = rabbit_event:notify(
190-
binding_created,
191-
info(B) ++ [{user_who_performed_action, ActingUser}])
192-
end;
193-
true -> rabbit_misc:const({error, binding_not_found})
180+
ok = sync_route(#route{binding = B}, SrcDurable, DstDurable,
181+
fun mnesia:write/3),
182+
x_callback(transaction, Src, add_binding, B),
183+
Serial = rabbit_exchange:serial(Src),
184+
fun () ->
185+
x_callback(Serial, Src, add_binding, B),
186+
ok = rabbit_event:notify(
187+
binding_created,
188+
info(B) ++ [{user_who_performed_action, ActingUser}])
194189
end.
195190

196191
-spec remove(rabbit_types:binding()) -> bind_res().
@@ -208,7 +203,10 @@ remove(Binding, InnerFun, ActingUser) ->
208203
case mnesia:read(rabbit_route, B, write) of
209204
[] -> case mnesia:read(rabbit_durable_route, B, write) of
210205
[] -> rabbit_misc:const(ok);
211-
_ -> rabbit_misc:const({error, binding_not_found})
206+
%% We still delete the binding and run
207+
%% all post-delete functions if there is only
208+
%% a durable route in the database
209+
_ -> remove(Src, Dst, B, ActingUser)
212210
end;
213211
_ -> case InnerFun(Src, Dst) of
214212
ok -> remove(Src, Dst, B, ActingUser);

src/rabbit_channel.erl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,11 +1845,6 @@ binding_action(Fun, SourceNameBin0, DestinationType, DestinationNameBin0,
18451845
rabbit_amqqueue:not_found(Name);
18461846
{error, {resources_missing, [{absent, Q, Reason} | _]}} ->
18471847
rabbit_amqqueue:absent(Q, Reason);
1848-
{error, binding_not_found} ->
1849-
rabbit_misc:protocol_error(
1850-
not_found, "no binding ~s between ~s and ~s",
1851-
[RoutingKey, rabbit_misc:rs(ExchangeName),
1852-
rabbit_misc:rs(DestinationName)]);
18531848
{error, {binding_invalid, Fmt, Args}} ->
18541849
rabbit_misc:protocol_error(precondition_failed, Fmt, Args);
18551850
{error, #amqp_error{} = Error} ->

0 commit comments

Comments
 (0)