最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Is my non-blocking POST request retry logic using CompletableFuture overcomplicated? - Stack Overflow

programmeradmin2浏览0评论

I am implementing a non-blocking retry logic for a POST request in Java using CompletableFuture. The goal is to retry the request up to n times and return the final result (either success or failure) after all attempts are complete. Here's how I start the process:

sendClusterPost(restRouteOfNode, jwtToken, CLUSTER_POST_RETRY_ATTEMPT)
    .thenAccept(success -> {
        if (success) {
            logger.info("Cluster POST redirection succeeded for {}", restRouteOfNode);
        } else {
            logger.error("Cluster POST redirection failed for {}. Local node {} will fetch the stream.", 
                         restRouteOfNode, getServerSettings().getHostAddress());
            // Handle failure here.
        }
    })
    .exceptionally(ex -> {
        logger.error("Cluster POST encountered an exception: {}", ExceptionUtils.getStackTrace(ex));
        return null;
    });

Here is the logic for the CompletableFuture implementation:

public CompletableFuture<Boolean> sendClusterPost(String url, String clusterCommunicationToken, int retryAttempts) {
    CompletableFuture<Boolean> future = new CompletableFuture<>();

    vertx.executeBlocking(promise -> {
        try (CloseableHttpClient httpClient = getHttpClient()) {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(CLUSTER_POST_TIMEOUT_MS)
                .setConnectionRequestTimeout(CLUSTER_POST_TIMEOUT_MS)
                .setSocketTimeout(CLUSTER_POST_TIMEOUT_MS)
                .build();
            httpPost.setConfig(requestConfig);

            httpPost.setHeader(TokenFilterManager.TOKEN_HEADER_FOR_NODE_COMMUNICATION, clusterCommunicationToken);

            try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
                int statusCode = httpResponse.getStatusLine().getStatusCode();
                logger.info("Cluster POST Response Status: {}", statusCode);

                if (statusCode == HttpStatus.SC_OK) {
                    promiseplete(true);
                } else if (retryAttempts > 0) {
                    logger.info("Retrying Cluster POST in {} ms due to non-200 response: {}", 
                                 appSettings.getWebhookRetryDelay(), statusCode);
                    retrySendClusterPostWithDelay(url, clusterCommunicationToken, retryAttempts - 1)
                        .thenAccept(promise::complete);
                } else {
                    logger.info("No more retry attempts left. Giving up.");
                    promiseplete(false);
                }
            }
        } catch (IOException e) {
            if (retryAttempts > 0) {
                logger.info("Retrying Cluster POST in {} ms due to IOException: {}", 
                             appSettings.getWebhookRetryDelay(), ExceptionUtils.getStackTrace(e));
                retrySendClusterPostWithDelay(url, clusterCommunicationToken, retryAttempts - 1)
                    .thenAccept(promise::complete);
            } else {
                logger.info("No more retry attempts left. Giving up.");
                promiseplete(false);
            }
        }
    }, result -> {
        if (result.succeeded()) {
            futureplete((Boolean) result.result());
        } else {
            futurepleteExceptionally(result.cause());
        }
    });

    return future;
}

public CompletableFuture<Boolean> retrySendClusterPostWithDelay(String url, String clusterCommunicationToken, int retryAttempts) {
    CompletableFuture<Boolean> future = new CompletableFuture<>();
    vertx.setTimer(appSettings.getWebhookRetryDelay(), timerId -> 
        sendClusterPost(url, clusterCommunicationToken, retryAttempts).thenAccept(future::complete)
    );
    return future;
}

I'm not very experienced with CompletableFuture, and while this implementation looks correct, I feel it might be overcomplicated. Specifically:

Is this a proper non-blocking implementation for retry logic?

Are there any redundant or unnecessary parts in this code that could be simplified without compromising functionality?

Any suggestions for improvement or simplification are appreciated!

发布评论

评论列表(0)

  1. 暂无评论