@@ -191,82 +191,6 @@ static uint32_t s_get_system_fd_limit(void) {
191191#endif
192192}
193193
194- /**
195- * Calculate dynamic connection limit based on sum of active meta request requirements.
196- * Returns the minimum of: total required connections, client override, and system FD limit.
197- * Applies hysteresis to prevent rapid changes.
198- */
199- static uint32_t s_get_dynamic_max_active_connections (
200- struct aws_s3_client * client ,
201- struct aws_s3_meta_request * meta_request ) {
202- AWS_PRECONDITION (client );
203-
204- /* Load sum of all meta request requirements */
205- size_t total_size = aws_atomic_load_int (& client -> stats .total_required_connections );
206-
207- /* Overflow protection: Cap at uint32_t max if sum exceeds it */
208- uint32_t total ;
209- if (total_size > UINT32_MAX ) {
210- total = UINT32_MAX ;
211- AWS_LOGF_WARN (
212- AWS_LS_S3_CLIENT ,
213- "id=%p Total required connections (%zu) exceeds uint32_t max, capping at %u" ,
214- (void * )client ,
215- total_size ,
216- UINT32_MAX );
217- } else {
218- total = (uint32_t )total_size ;
219- }
220-
221- /* Handle zero case - keep minimum connections alive */
222- if (total == 0 ) {
223- return g_min_num_connections ;
224- }
225-
226- /* Calculate new max connections value */
227- uint32_t new_max = total ;
228-
229- /* Apply user's throughput-based override if set */
230- if (client -> max_active_connections_override > 0 ) {
231- new_max = aws_min_u32 (new_max , client -> max_active_connections_override );
232- }
233-
234- /* respect meta request level overrides */
235- if (meta_request && meta_request -> max_active_connections_override > 0 ) {
236- new_max = aws_min_u32 (new_max , meta_request -> max_active_connections_override );
237- }
238-
239- /* Apply system FD limit (checked dynamically) */
240- uint32_t system_fd_limit = s_get_system_fd_limit ();
241-
242- /* Additional overflow protection: if system limit is 0 (getrlimit failed) */
243- if (system_fd_limit == 0 ) {
244- AWS_LOGF_WARN (
245- AWS_LS_S3_CLIENT ,
246- "id=%p System FD limit query failed, using fallback value of %u" ,
247- (void * )client ,
248- system_fd_limit );
249- }
250-
251- new_max = aws_min_u32 (new_max , system_fd_limit );
252-
253- /* Log warning if system limit is the bottleneck */
254- if (new_max == system_fd_limit &&
255- (total > system_fd_limit ||
256- (client -> max_active_connections_override > 0 && client -> max_active_connections_override > system_fd_limit ))) {
257- AWS_LOGF_DEBUG (
258- AWS_LS_S3_CLIENT ,
259- "id=%p Connection limit capped by system FD limit. "
260- "Workload requires %u connections, config allows %u, but system limits to %u" ,
261- (void * )client ,
262- total ,
263- client -> max_active_connections_override > 0 ? client -> max_active_connections_override : total ,
264- system_fd_limit );
265- }
266-
267- return new_max ;
268- }
269-
270194/* Returns the max number of connections allowed.
271195 *
272196 * When meta request is NULL, this will return the overall allowed number of connections based on the clinet
@@ -280,16 +204,26 @@ uint32_t aws_s3_client_get_max_active_connections(
280204 struct aws_s3_meta_request * meta_request ) {
281205 AWS_PRECONDITION (client );
282206
283- /* Check feature flag - use dynamic scaling if enabled */
284- if (client -> enable_dynamic_connection_scaling ) {
285- return s_get_dynamic_max_active_connections (client , meta_request );
286- }
287207 uint32_t max_active_connections = client -> ideal_connection_count ;
208+
209+ /* Respect total_required_connections calculated */
210+ size_t total_required = aws_atomic_load_int (& client -> stats .total_required_connections );
211+ if (total_required > 0 ) {
212+ max_active_connections = aws_min_u32 ((uint32_t )total_required , max_active_connections );
213+ }
214+
215+ /* Respect user override */
288216 if (client -> max_active_connections_override > 0 &&
289217 client -> max_active_connections_override < max_active_connections ) {
290218 max_active_connections = client -> max_active_connections_override ;
291219 }
220+
292221 if (meta_request ) {
222+ /* Total number of connections for a meta request should not exceed number of parts */
223+ if (meta_request -> object_size && meta_request -> part_size ) {
224+ max_active_connections =
225+ aws_min_u32 (meta_request -> object_size / meta_request -> part_size , max_active_connections );
226+ }
293227 if (meta_request -> max_active_connections_override ) {
294228 /* Apply the meta request level override the max active connections, but less than the client side settings.
295229 */
@@ -2331,7 +2265,7 @@ void aws_s3_client_update_connections_threaded(struct aws_s3_client *client) {
23312265
23322266 struct aws_s3_request * request = aws_s3_client_dequeue_request_threaded (client );
23332267 struct aws_s3_meta_request * meta_request = request -> meta_request ;
2334- const uint32_t max_active_connections = aws_s3_client_get_max_active_connections ( client , meta_request );
2268+
23352269 /* As the request removed from the queue. Decrement the preparing track */
23362270 -- meta_request -> client_process_work_threaded_data .num_request_being_prepared ;
23372271 if (request -> is_noop ) {
@@ -2366,7 +2300,8 @@ void aws_s3_client_update_connections_threaded(struct aws_s3_client *client) {
23662300 /* Calculate: (meta_request->weight / client->total_weight) * 300 */
23672301 double weight_ratio = meta_request -> weight / total_weight ;
23682302 uint32_t allowed_connections = (uint32_t )(weight_ratio * client_max_active_connections );
2369-
2303+ const uint32_t max_active_connections =
2304+ aws_s3_client_get_max_active_connections (client , meta_request );
23702305 allowed_connections = aws_min_u32 (allowed_connections , max_active_connections );
23712306
23722307 should_allocate_connection = (current_connections < allowed_connections );
0 commit comments