<commit_before>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package software.amazon.awssdk.http.nio.netty.internal.utils;

import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.CHANNEL_DIAGNOSTICS;

import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.EventLoop;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.handler.timeout.WriteTimeoutException;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise;
import io.netty.util.concurrent.SucceededFuture;
import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.http.nio.netty.internal.ChannelDiagnostics;
import software.amazon.awssdk.utils.FunctionalUtils;
import software.amazon.awssdk.utils.Logger;

@SdkInternalApi
public final class NettyUtils {
    /**
     * Completed succeed future.
     */
    public static final SucceededFuture<?> SUCCEEDED_FUTURE = new SucceededFuture<>(null, null);

    private static final Logger log = Logger.loggerFor(NettyUtils.class);

    private NettyUtils() {
    }

    public static Throwable decorateException(Channel channel, Throwable originalCause) {
        if (isAcquireTimeoutException(originalCause)) {
            return new Throwable(getMessageForAcquireTimeoutException(), originalCause);
        } else if (isTooManyPendingAcquiresException(originalCause)) {
            return new Throwable(getMessageForTooManyAcquireOperationsError(), originalCause);
        } else if (originalCause instanceof ReadTimeoutException) {
            return new IOException("Read timed out", originalCause);
        } else if (originalCause instanceof WriteTimeoutException) {
            return new IOException("Write timed out", originalCause);
        } else if (originalCause instanceof ClosedChannelException || isConnectionResetException(originalCause)) {
            return new IOException(NettyUtils.closedChannelMessage(channel), originalCause);
        }

        return originalCause;
    }

    private static boolean isConnectionResetException(Throwable originalCause) {
        return originalCause instanceof IOException && originalCause.getMessage().contains("Connection reset by peer");
    }

    private static boolean isAcquireTimeoutException(Throwable originalCause) {
        String message = originalCause.getMessage();
        return originalCause instanceof TimeoutException &&
               message != null &&
               message.contains("Acquire operation took longer");
    }

    private static boolean isTooManyPendingAcquiresException(Throwable originalCause) {
        String message = originalCause.getMessage();
        return originalCause instanceof IllegalStateException &&
               message != null &&
               originalCause.getMessage().contains("Too many outstanding acquire operations");
    }

    private static String getMessageForAcquireTimeoutException() {
        return "Acquire operation took longer than the configured maximum time. This indicates that a request cannot get a "
               + "connection from the pool within the specified maximum time. This can be due to high request rate.\n"

               + "Consider taking any of the following actions to mitigate the issue: increase max connections, "
               + "increase acquire timeout, or slowing the request rate.\n"

               + "Increasing the max connections can increase client throughput (unless the network interface is already "
               + "fully utilized), but can eventually start to hit operation system limitations on the number of file "
               + "descriptors used by the process. If you already are fully utilizing your network interface or cannot "
               + "further increase your connection count, increasing the acquire timeout gives extra time for requests to "
               + "acquire a connection before timing out. If the connections doesn't free up, the subsequent requests "
               + "will still timeout.\n"

               + "If the above mechanisms are not able to fix the issue, try smoothing out your requests so that large "
               + "traffic bursts cannot overload the client, being more efficient with the number of times you need to "
               + "call AWS, or by increasing the number of hosts sending requests.";
    }

    private static String getMessageForTooManyAcquireOperationsError() {
        return "Maximum pending connection acquisitions exceeded. The request rate is too high for the client to keep up.\n"

               + "Consider taking any of the following actions to mitigate the issue: increase max connections, "
               + "increase max pending acquire count, decrease pool lease timeout, or slowing the request rate.\n"

               + "Increasing the max connections can increase client throughput (unless the network interface is already "
               + "fully utilized), but can eventually start to hit operation system limitations on the number of file "<commit_msg>Clarify error message in Runnable Request (#3393)<commit_after>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package software.amazon.awssdk.http.nio.netty.internal.utils;

import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.CHANNEL_DIAGNOSTICS;

import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.EventLoop;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.handler.timeout.WriteTimeoutException;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise;
import io.netty.util.concurrent.SucceededFuture;
import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.http.nio.netty.internal.ChannelDiagnostics;
import software.amazon.awssdk.utils.FunctionalUtils;
import software.amazon.awssdk.utils.Logger;

@SdkInternalApi
public final class NettyUtils {
    /**
     * Completed succeed future.
     */
    public static final SucceededFuture<?> SUCCEEDED_FUTURE = new SucceededFuture<>(null, null);

    private static final Logger log = Logger.loggerFor(NettyUtils.class);

    private NettyUtils() {
    }

    public static Throwable decorateException(Channel channel, Throwable originalCause) {
        if (isAcquireTimeoutException(originalCause)) {
            return new Throwable(getMessageForAcquireTimeoutException(), originalCause);
        } else if (isTooManyPendingAcquiresException(originalCause)) {
            return new Throwable(getMessageForTooManyAcquireOperationsError(), originalCause);
        } else if (originalCause instanceof ReadTimeoutException) {
            return new IOException("Read timed out", originalCause);
        } else if (originalCause instanceof WriteTimeoutException) {
            return new IOException("Write timed out", originalCause);
        } else if (originalCause instanceof ClosedChannelException || isConnectionResetException(originalCause)) {
            return new IOException(NettyUtils.closedChannelMessage(channel), originalCause);
        }

        return originalCause;
    }

    private static boolean isConnectionResetException(Throwable originalCause) {
        return originalCause instanceof IOException && originalCause.getMessage().contains("Connection reset by peer");
    }

    private static boolean isAcquireTimeoutException(Throwable originalCause) {
        String message = originalCause.getMessage();
        return originalCause instanceof TimeoutException &&
               message != null &&
               message.contains("Acquire operation took longer");
    }

    private static boolean isTooManyPendingAcquiresException(Throwable originalCause) {
        String message = originalCause.getMessage();
        return originalCause instanceof IllegalStateException &&
               message != null &&
               originalCause.getMessage().contains("Too many outstanding acquire operations");
    }

    private static String getMessageForAcquireTimeoutException() {
        return "Acquire operation took longer than the configured maximum time. This indicates that a request cannot get a "
               + "connection from the pool within the specified maximum time. This can be due to high request rate.\n"

               + "Consider taking any of the following actions to mitigate the issue: increase max connections, "
               + "increase acquire timeout, or slowing the request rate.\n"

               + "Increasing the max connections can increase client throughput (unless the network interface is already "
               + "fully utilized), but can eventually start to hit operation system limitations on the number of file "
               + "descriptors used by the process. If you already are fully utilizing your network interface or cannot "
               + "further increase your connection count, increasing the acquire timeout gives extra time for requests to "
               + "acquire a connection before timing out. If the connections doesn't free up, the subsequent requests "
               + "will still timeout.\n"

               + "If the above mechanisms are not able to fix the issue, try smoothing out your requests so that large "
               + "traffic bursts cannot overload the client, being more efficient with the number of times you need to "
               + "call AWS, or by increasing the number of hosts sending requests.";
    }

    private static String getMessageForTooManyAcquireOperationsError() {
        return "Maximum pending connection acquisitions exceeded. The request rate is too high for the client to keep up.\n"

               + "Consider taking any of the following actions to mitigate the issue: increase max connections, "
               + "increase max pending acquire count, decrease connection acquisition timeout, or "
               + "slow the request rate.\n"

               + "Increasing the max connections can increase client throughput (unless the network interface is already "
               + "fully utilized), but can eventually start to hit operation system limitations on the number of file "
{'fraction_non_alphanumeric': 0.07082900311775521, 'fraction_numerical': 0.0009593092973059397, 'mean_word_length': 3.5757132406730068, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3147047', 'n_tokens_mistral': 3033, 'n_tokens_neox': 2917, 'n_words': 1088}