50
50
% % or by remote-incoming window (i.e. session flow control).
51
51
-define (DEFAULT_MAX_QUEUE_CREDIT , 256 ).
52
52
-define (DEFAULT_MAX_INCOMING_WINDOW , 400 ).
53
- -define (MAX_LINK_CREDIT , persistent_term :get (max_link_credit )).
54
53
-define (MAX_MANAGEMENT_LINK_CREDIT , 8 ).
55
54
-define (MANAGEMENT_NODE_ADDRESS , <<" /management" >>).
56
55
-define (UINT_OUTGOING_WINDOW , {uint , ? UINT_MAX }).
253
252
resource_alarms :: sets :set (rabbit_alarm :resource_alarm_source ()),
254
253
trace_state :: rabbit_trace :state (),
255
254
conn_name :: binary (),
256
- max_incoming_window :: pos_integer ()
255
+ max_incoming_window :: pos_integer (),
256
+ max_link_credit :: pos_integer (),
257
+ max_queue_credit :: pos_integer ()
257
258
}).
258
259
259
260
-record (state , {
@@ -386,8 +387,6 @@ init({ReaderPid, WriterPid, ChannelNum, MaxFrameSize, User, Vhost, ConnName,
386
387
true = is_valid_max (MaxLinkCredit ),
387
388
true = is_valid_max (MaxQueueCredit ),
388
389
true = is_valid_max (MaxIncomingWindow ),
389
- ok = persistent_term :put (max_link_credit , MaxLinkCredit ),
390
- ok = persistent_term :put (max_queue_credit , MaxQueueCredit ),
391
390
IncomingWindow = case sets :is_empty (Alarms ) of
392
391
true -> MaxIncomingWindow ;
393
392
false -> 0
@@ -420,7 +419,9 @@ init({ReaderPid, WriterPid, ChannelNum, MaxFrameSize, User, Vhost, ConnName,
420
419
resource_alarms = Alarms ,
421
420
trace_state = rabbit_trace :init (Vhost ),
422
421
conn_name = ConnName ,
423
- max_incoming_window = MaxIncomingWindow
422
+ max_incoming_window = MaxIncomingWindow ,
423
+ max_link_credit = MaxLinkCredit ,
424
+ max_queue_credit = MaxQueueCredit
424
425
}}}.
425
426
426
427
terminate (_Reason , # state {incoming_links = IncomingLinks ,
@@ -582,7 +583,8 @@ send_delivery_state_changes(#state{stashed_rejected = [],
582
583
stashed_eol = []} = State ) ->
583
584
State ;
584
585
send_delivery_state_changes (State0 = # state {cfg = # cfg {writer_pid = Writer ,
585
- channel_num = ChannelNum }}) ->
586
+ channel_num = ChannelNum ,
587
+ max_link_credit = MaxLinkCredit }}) ->
586
588
% % Order is important:
587
589
% % 1. Process queue rejections.
588
590
{RejectedIds , GrantCredits0 , State1 } = handle_stashed_rejected (State0 ),
@@ -603,15 +605,16 @@ send_delivery_state_changes(State0 = #state{cfg = #cfg{writer_pid = Writer,
603
605
rabbit_amqp_writer :send_command (Writer , ChannelNum , Frame )
604
606
end , DetachFrames ),
605
607
maps :foreach (fun (HandleInt , DeliveryCount ) ->
606
- F0 = flow (? UINT (HandleInt ), DeliveryCount ),
608
+ F0 = flow (? UINT (HandleInt ), DeliveryCount , MaxLinkCredit ),
607
609
F = session_flow_fields (F0 , State ),
608
610
rabbit_amqp_writer :send_command (Writer , ChannelNum , F )
609
611
end , GrantCredits ),
610
612
State .
611
613
612
614
handle_stashed_rejected (# state {stashed_rejected = []} = State ) ->
613
615
{[], #{}, State };
614
- handle_stashed_rejected (# state {stashed_rejected = Actions ,
616
+ handle_stashed_rejected (# state {cfg = # cfg {max_link_credit = MaxLinkCredit },
617
+ stashed_rejected = Actions ,
615
618
incoming_links = Links } = State0 ) ->
616
619
{Ids , GrantCredits , Ls } =
617
620
lists :foldl (
@@ -628,7 +631,8 @@ handle_stashed_rejected(#state{stashed_rejected = Actions,
628
631
end ,
629
632
Link1 = Link0 # incoming_link {incoming_unconfirmed_map = U },
630
633
{Link , GrantCreds } = maybe_grant_link_credit (
631
- HandleInt , Link1 , GrantCreds0 ),
634
+ MaxLinkCredit , HandleInt ,
635
+ Link1 , GrantCreds0 ),
632
636
{Ids1 , GrantCreds , maps :update (HandleInt , Link , Links0 )};
633
637
error ->
634
638
Acc
@@ -645,7 +649,8 @@ handle_stashed_rejected(#state{stashed_rejected = Actions,
645
649
646
650
handle_stashed_settled (GrantCredits , # state {stashed_settled = []} = State ) ->
647
651
{[], GrantCredits , State };
648
- handle_stashed_settled (GrantCredits0 , # state {stashed_settled = Actions ,
652
+ handle_stashed_settled (GrantCredits0 , # state {cfg = # cfg {max_link_credit = MaxLinkCredit },
653
+ stashed_settled = Actions ,
649
654
incoming_links = Links } = State0 ) ->
650
655
{Ids , GrantCredits , Ls } =
651
656
lists :foldl (
@@ -674,7 +679,8 @@ handle_stashed_settled(GrantCredits0, #state{stashed_settled = Actions,
674
679
end ,
675
680
Link1 = Link0 # incoming_link {incoming_unconfirmed_map = U },
676
681
{Link , GrantCreds } = maybe_grant_link_credit (
677
- HandleInt , Link1 , GrantCreds0 ),
682
+ MaxLinkCredit , HandleInt ,
683
+ Link1 , GrantCreds0 ),
678
684
{Ids2 , GrantCreds , maps :update (HandleInt , Link , Links0 )};
679
685
_ ->
680
686
Acc
@@ -714,11 +720,14 @@ handle_stashed_down(#state{stashed_down = QNames,
714
720
715
721
handle_stashed_eol (DetachFrames , GrantCredits , # state {stashed_eol = []} = State ) ->
716
722
{[], [], DetachFrames , GrantCredits , State };
717
- handle_stashed_eol (DetachFrames0 , GrantCredits0 , # state {stashed_eol = Eols } = State0 ) ->
723
+ handle_stashed_eol (DetachFrames0 , GrantCredits0 , # state {cfg = # cfg {max_link_credit = MaxLinkCredit },
724
+ stashed_eol = Eols } = State0 ) ->
718
725
{ReleasedIs , AcceptedIds , DetachFrames , GrantCredits , State1 } =
719
726
lists :foldl (fun (QName , {RIds0 , AIds0 , DetachFrames1 , GrantCreds0 , S0 = # state {incoming_links = Links0 ,
720
727
queue_states = QStates0 }}) ->
721
- {RIds , AIds , GrantCreds1 , Links } = settle_eol (QName , {RIds0 , AIds0 , GrantCreds0 , Links0 }),
728
+ {RIds , AIds , GrantCreds1 , Links } = settle_eol (
729
+ QName , MaxLinkCredit ,
730
+ {RIds0 , AIds0 , GrantCreds0 , Links0 }),
722
731
QStates = rabbit_queue_type :remove (QName , QStates0 ),
723
732
S1 = S0 # state {incoming_links = Links ,
724
733
queue_states = QStates },
@@ -729,14 +738,14 @@ handle_stashed_eol(DetachFrames0, GrantCredits0, #state{stashed_eol = Eols} = St
729
738
State = State1 # state {stashed_eol = []},
730
739
{ReleasedIs , AcceptedIds , DetachFrames , GrantCredits , State }.
731
740
732
- settle_eol (QName , {_ReleasedIds , _AcceptedIds , _GrantCredits , Links } = Acc ) ->
741
+ settle_eol (QName , MaxLinkCredit , {_ReleasedIds , _AcceptedIds , _GrantCredits , Links } = Acc ) ->
733
742
maps :fold (fun (HandleInt ,
734
743
# incoming_link {incoming_unconfirmed_map = U0 } = Link0 ,
735
744
{RelIds0 , AcceptIds0 , GrantCreds0 , Links0 }) ->
736
745
{RelIds , AcceptIds , U } = settle_eol0 (QName , {RelIds0 , AcceptIds0 , U0 }),
737
746
Link1 = Link0 # incoming_link {incoming_unconfirmed_map = U },
738
747
{Link , GrantCreds } = maybe_grant_link_credit (
739
- HandleInt , Link1 , GrantCreds0 ),
748
+ MaxLinkCredit , HandleInt , Link1 , GrantCreds0 ),
740
749
Links1 = maps :update (HandleInt ,
741
750
Link ,
742
751
Links0 ),
@@ -984,7 +993,8 @@ handle_control(#'v1_0.attach'{role = ?AMQP_ROLE_SENDER,
984
993
} = Attach ,
985
994
State0 = # state {incoming_links = IncomingLinks0 ,
986
995
permission_cache = PermCache0 ,
987
- cfg = # cfg {vhost = Vhost ,
996
+ cfg = # cfg {max_link_credit = MaxLinkCredit ,
997
+ vhost = Vhost ,
988
998
user = User }}) ->
989
999
ok = validate_attach (Attach ),
990
1000
case ensure_target (Target , Vhost , User , PermCache0 ) of
@@ -994,7 +1004,7 @@ handle_control(#'v1_0.attach'{role = ?AMQP_ROLE_SENDER,
994
1004
routing_key = RoutingKey ,
995
1005
queue_name_bin = QNameBin ,
996
1006
delivery_count = DeliveryCountInt ,
997
- credit = ? MAX_LINK_CREDIT },
1007
+ credit = MaxLinkCredit },
998
1008
_Outcomes = outcomes (Source ),
999
1009
Reply = # 'v1_0.attach' {
1000
1010
name = LinkName ,
@@ -1008,7 +1018,7 @@ handle_control(#'v1_0.attach'{role = ?AMQP_ROLE_SENDER,
1008
1018
max_message_size = {ulong , persistent_term :get (max_message_size )}},
1009
1019
Flow = # 'v1_0.flow' {handle = Handle ,
1010
1020
delivery_count = DeliveryCount ,
1011
- link_credit = ? UINT (? MAX_LINK_CREDIT )},
1021
+ link_credit = ? UINT (MaxLinkCredit )},
1012
1022
% %TODO check that handle is not in use for any other open links.
1013
1023
% %"The handle MUST NOT be used for other open links. An attempt to attach
1014
1024
% % using a handle which is already associated with a link MUST be responded to
@@ -1458,7 +1468,7 @@ handle_credit_reply0(
1458
1468
CCredit > 0 ->
1459
1469
QName = Link0 # outgoing_link .queue_name ,
1460
1470
% % Provide queue next batch of credits.
1461
- CappedCredit = cap_credit (CCredit ),
1471
+ CappedCredit = cap_credit (CCredit , S0 # state . cfg # cfg . max_queue_credit ),
1462
1472
{ok , QStates , Actions } =
1463
1473
rabbit_queue_type :credit (
1464
1474
QName , Ctag , DeliveryCount , CappedCredit , false , QStates0 ),
@@ -1496,7 +1506,8 @@ handle_credit_reply0(
1496
1506
} = QFC ,
1497
1507
stashed_credit_req = StashedCreditReq },
1498
1508
S0 = # state {cfg = # cfg {writer_pid = Writer ,
1499
- channel_num = ChanNum },
1509
+ channel_num = ChanNum ,
1510
+ max_queue_credit = MaxQueueCredit },
1500
1511
outgoing_links = OutgoingLinks ,
1501
1512
queue_states = QStates0 }) ->
1502
1513
% % If the queue sent us a drain credit_reply,
@@ -1512,7 +1523,7 @@ handle_credit_reply0(
1512
1523
% % the current drain credit top-up rounds over a stashed credit request because
1513
1524
% % this is easier to reason about and the queue will reply promptly meaning
1514
1525
% % the stashed request will be processed soon enough.
1515
- CappedCredit = cap_credit (CCredit ),
1526
+ CappedCredit = cap_credit (CCredit , MaxQueueCredit ),
1516
1527
{ok , QStates , Actions } = rabbit_queue_type :credit (
1517
1528
QName , Ctag , DeliveryCount ,
1518
1529
CappedCredit , true , QStates0 ),
@@ -1578,11 +1589,12 @@ pop_credit_req(
1578
1589
drain = Drain ,
1579
1590
echo = Echo
1580
1591
}},
1581
- S0 = # state {outgoing_links = OutgoingLinks ,
1592
+ S0 = # state {cfg = # cfg {max_queue_credit = MaxQueueCredit },
1593
+ outgoing_links = OutgoingLinks ,
1582
1594
queue_states = QStates0 }) ->
1583
1595
LinkCreditSnd = amqp10_util :link_credit_snd (
1584
1596
DeliveryCountRcv , LinkCreditRcv , CDeliveryCount ),
1585
- CappedCredit = cap_credit (LinkCreditSnd ),
1597
+ CappedCredit = cap_credit (LinkCreditSnd , MaxQueueCredit ),
1586
1598
{ok , QStates , Actions } = rabbit_queue_type :credit (
1587
1599
QName , Ctag , QDeliveryCount ,
1588
1600
CappedCredit , Drain , QStates0 ),
@@ -1753,7 +1765,8 @@ sent_pending_delivery(
1753
1765
% % assertion
1754
1766
none = Link0 # outgoing_link .stashed_credit_req ,
1755
1767
% % Provide queue next batch of credits.
1756
- CappedCredit = cap_credit (CCredit ),
1768
+ CappedCredit = cap_credit (CCredit ,
1769
+ S0 # state .cfg # cfg .max_queue_credit ),
1757
1770
{ok , QStates1 , Actions0 } =
1758
1771
rabbit_queue_type :credit (
1759
1772
QName , Ctag , QDeliveryCount , CappedCredit ,
@@ -1891,11 +1904,6 @@ settle_op_from_outcome(Outcome) ->
1891
1904
" Unrecognised state: ~tp in DISPOSITION" ,
1892
1905
[Outcome ]).
1893
1906
1894
- -spec flow ({uint , link_handle ()}, sequence_no ()) ->
1895
- # 'v1_0.flow' {}.
1896
- flow (Handle , DeliveryCount ) ->
1897
- flow (Handle , DeliveryCount , ? MAX_LINK_CREDIT ).
1898
-
1899
1907
-spec flow ({uint , link_handle ()}, sequence_no (), rabbit_queue_type :credit ()) ->
1900
1908
# 'v1_0.flow' {}.
1901
1909
flow (Handle , DeliveryCount , LinkCredit ) ->
@@ -2281,7 +2289,8 @@ incoming_link_transfer(
2281
2289
vhost = Vhost ,
2282
2290
trace_state = Trace ,
2283
2291
conn_name = ConnName ,
2284
- channel_num = ChannelNum }}) ->
2292
+ channel_num = ChannelNum ,
2293
+ max_link_credit = MaxLinkCredit }}) ->
2285
2294
2286
2295
{PayloadBin , DeliveryId , Settled } =
2287
2296
case MultiTransfer of
@@ -2326,7 +2335,8 @@ incoming_link_transfer(
2326
2335
DeliveryCount = add (DeliveryCount0 , 1 ),
2327
2336
Credit1 = Credit0 - 1 ,
2328
2337
{Credit , Reply1 } = maybe_grant_link_credit (
2329
- Credit1 , DeliveryCount , map_size (U ), Handle ),
2338
+ Credit1 , MaxLinkCredit ,
2339
+ DeliveryCount , map_size (U ), Handle ),
2330
2340
Reply = Reply0 ++ Reply1 ,
2331
2341
Link = Link0 # incoming_link {
2332
2342
delivery_count = DeliveryCount ,
@@ -2420,30 +2430,30 @@ released(DeliveryId) ->
2420
2430
settled = true ,
2421
2431
state = # 'v1_0.released' {}}.
2422
2432
2423
- maybe_grant_link_credit (Credit , DeliveryCount , NumUnconfirmed , Handle ) ->
2424
- case grant_link_credit (Credit , NumUnconfirmed ) of
2433
+ maybe_grant_link_credit (Credit , MaxLinkCredit , DeliveryCount , NumUnconfirmed , Handle ) ->
2434
+ case grant_link_credit (Credit , MaxLinkCredit , NumUnconfirmed ) of
2425
2435
true ->
2426
- {? MAX_LINK_CREDIT , [flow (Handle , DeliveryCount )]};
2436
+ {MaxLinkCredit , [flow (Handle , DeliveryCount , MaxLinkCredit )]};
2427
2437
false ->
2428
2438
{Credit , []}
2429
2439
end .
2430
2440
2431
2441
maybe_grant_link_credit (
2442
+ MaxLinkCredit ,
2432
2443
HandleInt ,
2433
2444
Link = # incoming_link {credit = Credit ,
2434
2445
incoming_unconfirmed_map = U ,
2435
2446
delivery_count = DeliveryCount },
2436
2447
AccMap ) ->
2437
- case grant_link_credit (Credit , map_size (U )) of
2448
+ case grant_link_credit (Credit , MaxLinkCredit , map_size (U )) of
2438
2449
true ->
2439
- {Link # incoming_link {credit = ? MAX_LINK_CREDIT },
2450
+ {Link # incoming_link {credit = MaxLinkCredit },
2440
2451
AccMap #{HandleInt => DeliveryCount }};
2441
2452
false ->
2442
2453
{Link , AccMap }
2443
2454
end .
2444
2455
2445
- grant_link_credit (Credit , NumUnconfirmed ) ->
2446
- MaxLinkCredit = ? MAX_LINK_CREDIT ,
2456
+ grant_link_credit (Credit , MaxLinkCredit , NumUnconfirmed ) ->
2447
2457
Credit =< MaxLinkCredit div 2 andalso
2448
2458
NumUnconfirmed < MaxLinkCredit .
2449
2459
@@ -2739,7 +2749,8 @@ handle_outgoing_link_flow_control(
2739
2749
DeliveryCountRcv ,
2740
2750
LinkCreditRcv ,
2741
2751
CFC # client_flow_ctl .delivery_count ),
2742
- CappedCredit = cap_credit (LinkCreditSnd ),
2752
+ CappedCredit = cap_credit (LinkCreditSnd ,
2753
+ State0 # state .cfg # cfg .max_queue_credit ),
2743
2754
Link = Link0 # outgoing_link {
2744
2755
client_flow_ctl = CFC # client_flow_ctl {
2745
2756
credit = LinkCreditSnd ,
@@ -3444,10 +3455,9 @@ is_valid_max(Val) ->
3444
3455
pg_scope () ->
3445
3456
rabbit :pg_local_scope (amqp_session ).
3446
3457
3447
- -spec cap_credit (rabbit_queue_type :credit ()) ->
3458
+ -spec cap_credit (rabbit_queue_type :credit (), pos_integer () ) ->
3448
3459
rabbit_queue_type :credit ().
3449
- cap_credit (DesiredCredit ) ->
3450
- MaxCredit = persistent_term :get (max_queue_credit ),
3460
+ cap_credit (DesiredCredit , MaxCredit ) ->
3451
3461
min (DesiredCredit , MaxCredit ).
3452
3462
3453
3463
ensure_mc_cluster_compat (Mc ) ->
0 commit comments