@@ -366,109 +366,89 @@ record_death(Reason, SourceQueue,
366
366
? ANN_ROUTING_KEYS := RoutingKeys } = Anns0 ,
367
367
Timestamp = os :system_time (millisecond ),
368
368
Ttl = maps :get (ttl , Anns0 , undefined ),
369
-
370
- ReasonBin = atom_to_binary (Reason ),
371
369
DeathAnns = rabbit_misc :maps_put_truthy (ttl , Ttl , #{first_time => Timestamp ,
372
370
last_time => Timestamp }),
373
- case maps :get (deaths , Anns0 , undefined ) of
374
- undefined ->
375
- case rabbit_feature_flags :is_enabled (message_containers_deaths_v2 ) of
376
- true ->
377
- record_death_v2 (SourceQueue , Reason , ReasonBin , Exchange ,
378
- RoutingKeys , Timestamp , Ttl , State );
379
- false ->
380
- Ds = # deaths {last = Key ,
381
- first = Key ,
382
- records = #{Key => # death {count = 1 ,
383
- exchange = Exchange ,
384
- routing_keys = RoutingKeys ,
385
- anns = DeathAnns }}},
386
- Anns = Anns0 #{<<" x-first-death-reason" >> => ReasonBin ,
387
- <<" x-first-death-queue" >> => SourceQueue ,
388
- <<" x-first-death-exchange" >> => Exchange ,
389
- <<" x-last-death-reason" >> => ReasonBin ,
390
- <<" x-last-death-queue" >> => SourceQueue ,
391
- <<" x-last-death-exchange" >> => Exchange ,
392
- deaths => Ds
393
- },
394
- State #? MODULE {annotations = Anns }
395
- end ;
396
- # deaths {records = Rs } = Ds0 ->
397
- Death = # death {count = C ,
398
- anns = DA } = maps :get (Key , Rs ,
399
- # death {exchange = Exchange ,
400
- routing_keys = RoutingKeys ,
401
- anns = DeathAnns }),
402
- Ds = Ds0 # deaths {last = Key ,
403
- records = Rs #{Key =>
404
- Death # death {count = C + 1 ,
405
- anns = DA #{last_time => Timestamp }}}},
406
- Anns = Anns0 #{deaths => Ds ,
371
+ case Anns0 of
372
+ #{deaths := Deaths = # deaths {records = Rs0 }} ->
373
+ Rs = if is_list (Rs0 ) ->
374
+ % % records are ordered by recency
375
+ case lists :keytake (Key , 1 , Rs0 ) of
376
+ {value , {Key , D0 }, Rs1 } ->
377
+ D = update_death (D0 , Timestamp ),
378
+ [{Key , D } | Rs1 ];
379
+ false ->
380
+ [{Key , # death {exchange = Exchange ,
381
+ routing_keys = RoutingKeys ,
382
+ count = 1 ,
383
+ anns = DeathAnns }} | Rs0 ]
384
+ end ;
385
+ is_map (Rs0 ) ->
386
+ case Rs0 of
387
+ #{Key := Death } ->
388
+ Rs0 #{Key := update_death (Death , Timestamp )};
389
+ _ ->
390
+ Rs0 #{Key => # death {exchange = Exchange ,
391
+ routing_keys = RoutingKeys ,
392
+ count = 1 ,
393
+ anns = DeathAnns }}
394
+ end
395
+ end ,
396
+ Anns = Anns0 #{<<" x-last-death-reason" >> := atom_to_binary (Reason ),
397
+ <<" x-last-death-queue" >> := SourceQueue ,
398
+ <<" x-last-death-exchange" >> := Exchange ,
399
+ deaths := Deaths # deaths {last = Key ,
400
+ records = Rs }},
401
+ State #? MODULE {annotations = Anns };
402
+ _ ->
403
+ Death = # death {exchange = Exchange ,
404
+ routing_keys = RoutingKeys ,
405
+ count = 1 ,
406
+ anns = DeathAnns },
407
+ Rs = case rabbit_feature_flags :is_enabled (message_containers_deaths_v2 ) of
408
+ true -> [{Key , Death }];
409
+ false -> #{Key => Death }
410
+ end ,
411
+ ReasonBin = atom_to_binary (Reason ),
412
+ Anns = Anns0 #{<<" x-first-death-reason" >> => ReasonBin ,
413
+ <<" x-first-death-queue" >> => SourceQueue ,
414
+ <<" x-first-death-exchange" >> => Exchange ,
407
415
<<" x-last-death-reason" >> => ReasonBin ,
408
416
<<" x-last-death-queue" >> => SourceQueue ,
409
- <<" x-last-death-exchange" >> => Exchange },
417
+ <<" x-last-death-exchange" >> => Exchange ,
418
+ deaths => # deaths {last = Key ,
419
+ first = Key ,
420
+ records = Rs }},
410
421
State #? MODULE {annotations = Anns }
411
422
end ;
412
423
record_death (Reason , SourceQueue , BasicMsg ) ->
413
424
mc_compat :record_death (Reason , SourceQueue , BasicMsg ).
414
425
415
- record_death_v2 (SourceQueue , Reason , ReasonBin , Exchange , RoutingKeys , Timestamp , Ttl ,
416
- #? MODULE {annotations = Anns0 } = State ) ->
417
- DeathAnns = rabbit_misc :maps_put_truthy (ttl , Ttl , #{}),
418
- Anns = case Anns0 of
419
- #{deaths_v2 := Deaths0 } ->
420
- % % deaths_v2 is ordered by recency
421
- Deaths = case deaths_take (SourceQueue , Reason , Deaths0 ) of
422
- {value , Death0 = # death_v2 {count = Count }, Deaths1 } ->
423
- Death = Death0 # death_v2 {count = Count + 1 },
424
- [Death | Deaths1 ];
425
- false ->
426
- Death = # death_v2 {source_queue = SourceQueue ,
427
- reason = Reason ,
428
- count = 1 ,
429
- first_death_timestamp = Timestamp ,
430
- original_exchange = Exchange ,
431
- original_routing_keys = RoutingKeys ,
432
- annotations = DeathAnns },
433
- [Death | Deaths0 ]
434
- end ,
435
- Anns0 #{deaths_v2 := Deaths ,
436
- <<" x-last-death-reason" >> := ReasonBin ,
437
- <<" x-last-death-queue" >> := SourceQueue ,
438
- <<" x-last-death-exchange" >> := Exchange };
439
- _ ->
440
- Death = # death_v2 {source_queue = SourceQueue ,
441
- reason = Reason ,
442
- count = 1 ,
443
- first_death_timestamp = Timestamp ,
444
- original_exchange = Exchange ,
445
- original_routing_keys = RoutingKeys ,
446
- annotations = DeathAnns },
447
- Anns0 #{deaths_v2 => [Death ],
448
- <<" x-first-death-reason" >> => ReasonBin ,
449
- <<" x-first-death-queue" >> => SourceQueue ,
450
- <<" x-first-death-exchange" >> => Exchange ,
451
- <<" x-last-death-reason" >> => ReasonBin ,
452
- <<" x-last-death-queue" >> => SourceQueue ,
453
- <<" x-last-death-exchange" >> => Exchange }
454
- end ,
455
- State #? MODULE {annotations = Anns }.
426
+ update_death (# death {count = Count ,
427
+ anns = DeathAnns } = Death , Timestamp ) ->
428
+ Death # death {count = Count + 1 ,
429
+ anns = DeathAnns #{last_time := Timestamp }}.
456
430
457
431
-spec is_death_cycle (rabbit_misc :resource_name (), state ()) -> boolean ().
458
- is_death_cycle (TargetQueue , #? MODULE {annotations = #{deaths_v2 := Deaths }}) ->
459
- is_cycle_v2 (TargetQueue , Deaths );
460
- is_death_cycle (TargetQueue , #? MODULE {annotations = #{deaths := Deaths }}) ->
461
- is_cycle_v1 (TargetQueue , maps :keys (Deaths # deaths .records ));
432
+ is_death_cycle (TargetQueue , #? MODULE {annotations = #{deaths := # deaths {records = Recs }}})
433
+ when is_list (Recs ) ->
434
+ is_cycle_v2 (TargetQueue , Recs );
435
+ is_death_cycle (TargetQueue , #? MODULE {annotations = #{deaths := # deaths {records = Recs }}})
436
+ when is_map (Recs ) ->
437
+ is_cycle_v1 (TargetQueue , maps :keys (Recs ));
462
438
is_death_cycle (_TargetQueue , #? MODULE {}) ->
463
439
false ;
464
440
is_death_cycle (TargetQueue , BasicMsg ) ->
465
441
mc_compat :is_death_cycle (TargetQueue , BasicMsg ).
466
442
467
443
% % Returns death queue names ordered by recency.
468
444
-spec death_queue_names (state ()) -> [rabbit_misc :resource_name ()].
469
- death_queue_names (#? MODULE {annotations = #{deaths_v2 := Deaths }}) ->
470
- lists :map (fun (# death_v2 {source_queue = Q }) -> Q end , Deaths );
471
- death_queue_names (#? MODULE {annotations = #{deaths := # deaths {records = Records }}}) ->
445
+ death_queue_names (#? MODULE {annotations = #{deaths := # deaths {records = Records }}})
446
+ when is_list (Records ) ->
447
+ lists :map (fun ({{Queue , _Reason }, _Death }) ->
448
+ Queue
449
+ end , Records );
450
+ death_queue_names (#? MODULE {annotations = #{deaths := # deaths {records = Records }}})
451
+ when is_map (Records ) ->
472
452
proplists :get_keys (maps :keys (Records ));
473
453
death_queue_names (#? MODULE {}) ->
474
454
[];
@@ -493,7 +473,7 @@ prepare(For, State) ->
493
473
% % INTERNAL
494
474
495
475
is_cycle_v2 (TargetQueue , Deaths ) ->
496
- case lists :splitwith (fun (# death_v2 { source_queue = SourceQueue }) ->
476
+ case lists :splitwith (fun ({{ SourceQueue , _Reason }, # death {} }) ->
497
477
SourceQueue =/= TargetQueue
498
478
end , Deaths ) of
499
479
{_ , []} ->
@@ -502,7 +482,7 @@ is_cycle_v2(TargetQueue, Deaths) ->
502
482
% % There is a cycle, but we only want to drop the message
503
483
% % if the cycle is "fully automatic", i.e. without a client
504
484
% % expliclity rejecting the message somewhere in the cycle.
505
- lists :all (fun (# death_v2 { reason = Reason }) ->
485
+ lists :all (fun ({{ _SourceQueue , Reason }, # death {} }) ->
506
486
Reason =/= rejected
507
487
end , [H | L ])
508
488
end .
@@ -527,17 +507,3 @@ is_cycle_v1(Queue, [_ | Rem]) ->
527
507
set_received_at_timestamp (Anns ) ->
528
508
Millis = os :system_time (millisecond ),
529
509
Anns #{? ANN_RECEIVED_AT_TIMESTAMP => Millis }.
530
-
531
- deaths_take (Queue , Reason , Deaths ) ->
532
- deaths_take (Queue , Reason , Deaths , []).
533
-
534
- deaths_take (Queue ,
535
- Reason ,
536
- [# death_v2 {source_queue = Queue ,
537
- reason = Reason } = H | T ],
538
- Acc ) ->
539
- {value , H , lists :reverse (Acc , T )};
540
- deaths_take (Queue , Reason , [H |T ], Acc ) ->
541
- deaths_take (Queue , Reason , T , [H |Acc ]);
542
- deaths_take (_Queue , _Reason , [], _Acc ) ->
543
- false .
0 commit comments