Build smaller match spec conditions rather than a single big one

Otherwise, we can trigger a stack overflow in the Erlang VM itself, as
described in ERL-592: https://bugs.erlang.org/browse/ERL-592

The code before works fine when 50k queues are being deleted out of 100k
queues, but fails when there are 150k queues in total & 50k need to be
deleted.

Partner-in-crime: @essen
This commit is contained in:
Gerhard Lazu 2018-03-22 17:06:59 +00:00 committed by Michael Klishin
parent c391c0468f
commit b04bc83b55
1 changed files with 13 additions and 3 deletions

View File

@ -244,11 +244,21 @@ queue_deleted(Name) ->
queues_deleted(Queues) ->
[ delete_queue_metrics(Queue) || Queue <- Queues ],
MatchSpecCondition = build_match_spec_conditions_to_delete_all_queues(Queues),
delete_channel_queue_exchange_metrics(MatchSpecCondition),
delete_channel_queue_metrics(MatchSpecCondition),
[
begin
MatchSpecCondition = build_match_spec_conditions_to_delete_all_queues(QueuesPartition),
delete_channel_queue_exchange_metrics(MatchSpecCondition),
delete_channel_queue_metrics(MatchSpecCondition)
end || QueuesPartition <- partition_queues(Queues)
],
ok.
partition_queues(Queues) when length(Queues) >= 1000 ->
{Partition, Rest} = lists:split(1000, Queues),
[Partition | partition_queues(Rest)];
partition_queues(Queues) ->
[Queues].
delete_queue_metrics(Queue) ->
ets:delete(queue_coarse_metrics, Queue),
ets:update_element(queue_metrics, Queue, {3, 1}),