@@ -111,9 +111,10 @@ recvloop(Deb, State0 = #v1{recv_len = RecvLen,
111111mainloop (Deb , State = # v1 {sock = Sock , buf = Buf , buf_len = BufLen }) ->
112112 case rabbit_net :recv (Sock ) of
113113 {data , Data } ->
114- recvloop (Deb , State # v1 {buf = [Data | Buf ],
115- buf_len = BufLen + size (Data ),
116- pending_recv = false });
114+ State1 = maybe_resize_buffer (State , Data ),
115+ recvloop (Deb , State1 # v1 {buf = [Data | Buf ],
116+ buf_len = BufLen + size (Data ),
117+ pending_recv = false });
117118 closed when State # v1 .connection_state =:= closed ->
118119 ok ;
119120 closed ->
@@ -130,6 +131,37 @@ mainloop(Deb, State = #v1{sock = Sock, buf = Buf, buf_len = BufLen}) ->
130131 end
131132 end .
132133
134+ maybe_resize_buffer (State = # v1 {sock = Sock , dynamic_buffer_size = BufferSize0 ,
135+ dynamic_buffer_moving_average = MovingAvg0 }, Data ) ->
136+ LowDynamicBuffer = 128 ,
137+ HighDynamicBuffer = 131072 ,
138+ DataLen = byte_size (Data ),
139+ MovingAvg = (MovingAvg0 * 7 + DataLen ) / 8 ,
140+ if
141+ BufferSize0 < HighDynamicBuffer andalso MovingAvg > BufferSize0 * 0.9 ->
142+ BufferSize = min (BufferSize0 * 2 , HighDynamicBuffer ),
143+ case rabbit_net :setopts (Sock , [{buffer , BufferSize }]) of
144+ ok -> State # v1 {
145+ dynamic_buffer_size = BufferSize ,
146+ dynamic_buffer_moving_average = MovingAvg
147+ };
148+ {error , Reason } ->
149+ throw ({inet_error , Reason })
150+ end ;
151+ BufferSize0 > LowDynamicBuffer andalso MovingAvg < BufferSize0 * 0.4 ->
152+ BufferSize = max (BufferSize0 div 2 , LowDynamicBuffer ),
153+ case rabbit_net :setopts (Sock , [{buffer , BufferSize }]) of
154+ ok -> State # v1 {
155+ dynamic_buffer_size = BufferSize ,
156+ dynamic_buffer_moving_average = MovingAvg
157+ };
158+ {error , Reason } ->
159+ throw ({inet_error , Reason })
160+ end ;
161+ true ->
162+ State # v1 {dynamic_buffer_moving_average = MovingAvg }
163+ end .
164+
133165-spec handle_other (any (), state ()) -> state () | stop .
134166handle_other (emit_stats , State ) ->
135167 emit_stats (State );
0 commit comments