9999 % % throttling state, for both
100100 % % credit- and resource-driven flow control
101101 throttle ,
102- proxy_socket }).
102+ proxy_socket ,
103+ % % dynamic buffer
104+ dynamic_buffer_size ,
105+ dynamic_buffer_moving_average
106+ }).
103107
104108-record (throttle , {
105109 % % never | timestamp()
@@ -512,8 +516,9 @@ mainloop(Deb, Buf, BufLen, State = #v1{sock = Sock,
512516 end ,
513517 case Recv of
514518 {data , Data } ->
519+ State1 = maybe_resize_buffer (State , Data ),
515520 recvloop (Deb , [Data | Buf ], BufLen + size (Data ),
516- State # v1 {pending_recv = false });
521+ State1 # v1 {pending_recv = false });
517522 closed when State # v1 .connection_state =:= closed ->
518523 State ;
519524 closed when CS =:= pre_init andalso Buf =:= [] ->
@@ -536,6 +541,37 @@ mainloop(Deb, Buf, BufLen, State = #v1{sock = Sock,
536541 end
537542 end .
538543
544+ maybe_resize_buffer (State = # v1 {sock = Sock , dynamic_buffer_size = BufferSize0 ,
545+ dynamic_buffer_moving_average = MovingAvg0 }, Data ) ->
546+ LowDynamicBuffer = 1024 ,
547+ HighDynamicBuffer = 131072 ,
548+ DataLen = byte_size (Data ),
549+ MovingAvg = (MovingAvg0 + DataLen ) div 2 ,
550+ if
551+ BufferSize0 < HighDynamicBuffer andalso MovingAvg > BufferSize0 * 0.9 ->
552+ BufferSize = min (BufferSize0 * 2 , HighDynamicBuffer ),
553+ case rabbit_net :setopts (Sock , [{buffer , BufferSize }]) of
554+ ok -> State # v1 {
555+ dynamic_buffer_size = BufferSize ,
556+ dynamic_buffer_moving_average = MovingAvg
557+ };
558+ Error ->
559+ stop (Error , State )
560+ end ;
561+ BufferSize0 > LowDynamicBuffer andalso MovingAvg < BufferSize0 * 0.4 ->
562+ BufferSize = max (BufferSize0 div 2 , LowDynamicBuffer ),
563+ case rabbit_net :setopts (Sock , [{buffer , BufferSize }]) of
564+ ok -> State # v1 {
565+ dynamic_buffer_size = BufferSize ,
566+ dynamic_buffer_moving_average = MovingAvg
567+ };
568+ Error ->
569+ stop (Error , State )
570+ end ;
571+ true ->
572+ State # v1 {dynamic_buffer_moving_average = MovingAvg }
573+ end .
574+
539575-spec stop (_ , # v1 {}) -> no_return ().
540576stop (tcp_healthcheck , State ) ->
541577 % % The connection was closed before any packet was received. It's
0 commit comments