Skip to content

Commit 7436e04

Browse files
committed
reduce queue/exchange deletion complexity
from O(binding_count^2) to O(binding_count)
1 parent 5930d04 commit 7436e04

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

src/rabbit_binding.erl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ has_for_source(SrcName) ->
277277
contains(rabbit_semi_durable_route, Match).
278278

279279
remove_for_source(SrcName) ->
280+
lock_route_tables(),
280281
Match = #route{binding = #binding{source = SrcName, _ = '_'}},
281282
Routes = lists:usort(
282283
mnesia:match_object(rabbit_route, Match, write) ++
@@ -351,7 +352,28 @@ continue('$end_of_table') -> false;
351352
continue({[_|_], _}) -> true;
352353
continue({[], Continuation}) -> continue(mnesia:select(Continuation)).
353354

355+
%% For bulk operations we lock the tables we are operating on in order
356+
%% to reduce the time complexity. Without the table locks we end up
357+
%% with num_tables*num_bulk_bindings row-level locks. Takiing each
358+
%% lock takes time proportional to the number of existing locks, thus
359+
%% resulting in O(num_bulk_bindings^2) complexity.
360+
%%
361+
%% The locks need to be write locks since ultimately we end up
362+
%% removing all these rows.
363+
%%
364+
%% The downside of all this is that no other binding operations except
365+
%% lookup/routing (which uses dirty ops) can take place
366+
%% concurrently. However, that is the case already since the bulk
367+
%% operations involve mnesia:match_object calls with a partial key,
368+
%% which entails taking a table lock.
369+
lock_route_tables() ->
370+
[mnesia:lock({table, T}, write) || T <- [rabbit_route,
371+
rabbit_reverse_route,
372+
rabbit_semi_durable_route,
373+
rabbit_durable_route]].
374+
354375
remove_for_destination(DstName, DeleteFun) ->
376+
lock_route_tables(),
355377
Match = reverse_route(
356378
#route{binding = #binding{destination = DstName, _ = '_'}}),
357379
ReverseRoutes = mnesia:match_object(rabbit_reverse_route, Match, write),

0 commit comments

Comments
 (0)