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!
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745601188a4635411.html
评论列表(0条)