|
47 | 47 | msg_id_to_channel, |
48 | 48 | ttl, |
49 | 49 | ttl_timer_ref, |
| 50 | + ttl_timer_expiry, |
50 | 51 | senders, |
51 | 52 | publish_seqno, |
52 | 53 | unconfirmed, |
@@ -559,7 +560,8 @@ deliver_or_enqueue(Delivery = #delivery{message = Message, |
559 | 560 | maybe_record_confirm_message(Confirm, State1), |
560 | 561 | Props = message_properties(Confirm, State2), |
561 | 562 | BQS1 = BQ:publish(Message, Props, SenderPid, BQS), |
562 | | - ensure_ttl_timer(State2#q{backing_queue_state = BQS1}) |
| 563 | + ensure_ttl_timer(Props#message_properties.expiry, |
| 564 | + State2#q{backing_queue_state = BQS1}) |
563 | 565 | end. |
564 | 566 |
|
565 | 567 | requeue_and_run(AckTags, State = #q{backing_queue = BQ}) -> |
@@ -699,28 +701,42 @@ drop_expired_messages(State = #q{backing_queue_state = BQS, |
699 | 701 | backing_queue = BQ }) -> |
700 | 702 | Now = now_micros(), |
701 | 703 | DLXFun = dead_letter_fun(expired, State), |
702 | | - ExpirePred = fun (#message_properties{expiry = Expiry}) -> Now > Expiry end, |
703 | | - case DLXFun of |
704 | | - undefined -> {undefined, BQS1} = BQ:dropwhile(ExpirePred, false, BQS), |
705 | | - BQS1; |
706 | | - _ -> {Msgs, BQS1} = BQ:dropwhile(ExpirePred, true, BQS), |
707 | | - lists:foreach( |
708 | | - fun({Msg, AckTag}) -> DLXFun(Msg, AckTag) end, Msgs), |
709 | | - BQS1 |
710 | | - end, |
711 | | - ensure_ttl_timer(State#q{backing_queue_state = BQS1}). |
712 | | - |
713 | | -ensure_ttl_timer(State = #q{backing_queue = BQ, |
714 | | - backing_queue_state = BQS, |
715 | | - ttl = TTL, |
716 | | - ttl_timer_ref = undefined}) |
717 | | - when TTL =/= undefined -> |
718 | | - case BQ:is_empty(BQS) of |
719 | | - true -> State; |
720 | | - false -> TRef = erlang:send_after(TTL, self(), drop_expired), |
721 | | - State#q{ttl_timer_ref = TRef} |
| 704 | + ExpirePred = fun (#message_properties{expiry = Exp}) -> Now >= Exp end, |
| 705 | + {Props, BQS1} = |
| 706 | + case DLXFun of |
| 707 | + undefined -> |
| 708 | + {Next, undefined, BQS2} = BQ:dropwhile(ExpirePred, false, BQS), |
| 709 | + {Next, BQS2}; |
| 710 | + _ -> |
| 711 | + {Next, Msgs, BQS2} = BQ:dropwhile(ExpirePred, true, BQS), |
| 712 | + lists:foreach(fun({Msg, AckTag}) -> DLXFun(Msg, AckTag) end, |
| 713 | + Msgs), |
| 714 | + {Next, BQS2} |
| 715 | + end, |
| 716 | + ensure_ttl_timer(case Props of |
| 717 | + undefined -> undefined; |
| 718 | + #message_properties{expiry = Exp} -> Exp |
| 719 | + end, State#q{backing_queue_state = BQS1}). |
| 720 | + |
| 721 | +ensure_ttl_timer(undefined, State) -> |
| 722 | + State; |
| 723 | +ensure_ttl_timer(_Expiry, State = #q{ttl = undefined}) -> |
| 724 | + State; |
| 725 | +ensure_ttl_timer(Expiry, State = #q{ttl_timer_ref = undefined}) -> |
| 726 | + After = (case Expiry - now_micros() of |
| 727 | + V when V > 0 -> V + 999; %% always fire later |
| 728 | + _ -> 0 |
| 729 | + end) div 1000, |
| 730 | + TRef = erlang:send_after(After, self(), drop_expired), |
| 731 | + State#q{ttl_timer_ref = TRef, ttl_timer_expiry = Expiry}; |
| 732 | +ensure_ttl_timer(Expiry, State = #q{ttl_timer_ref = TRef, |
| 733 | + ttl_timer_expiry = TExpiry}) |
| 734 | + when Expiry + 1000 < TExpiry -> |
| 735 | + case erlang:cancel_timer(TRef) of |
| 736 | + false -> State; |
| 737 | + _ -> ensure_ttl_timer(Expiry, State#q{ttl_timer_ref = undefined}) |
722 | 738 | end; |
723 | | -ensure_ttl_timer(State) -> |
| 739 | +ensure_ttl_timer(_Expiry, State) -> |
724 | 740 | State. |
725 | 741 |
|
726 | 742 | ack_if_no_dlx(AckTags, State = #q{dlx = undefined, |
|
0 commit comments