// calls post
public void call(String data) throws CustomException {
asyncHttpClient.post(data, 10);
}
// posts data to http endpoint
public void post(String data, int retries) throw CustomException {
// if retries are exhausted, throw CustomException to call()
if (retry <= 0) {
throw new CustomException("exc");
}
BoundRequest request = httpClient.preparePost("http_endpoint");
ListenableFuture<Response> responseFuture = httpClient.post(request);
responseFuture.addListener(() -> {
Response response = null;
int status = 0;
try {
response = responseFuture.get();
status = response.getStatusCode();
// HTTP_ACCEPTED = {200, 201, 202}
if (ArrayUtils.contains(HTTP_ACCEPTED, status)) {
// ok
} else {
sleep(10);
post(data, retry - 1);
}
} catch (InterruptedException e) {
sleep(10);
post(data, retry - 1);
} catch (ExecutionException e) {
// ConnectionException
// RequestTimeoutException
sleep(10); // 10 seconds
post(data, retry - 1);
} catch (Exception e) {
sleep(10); // 10 seconds
post(data, retry - 1 );
} finally {
responseFuture.done();
}
}, Runnable::run);
}
CustomException
似乎从未抛出,并且在重试==0之后,控件将返回到Finally
块。...
} catch (ExecutionException e) {
// ConnectionException
// RequestTimeoutException
sleep(10); // 10 seconds
try {
post(data, retry - 1);
} catch (CustomException e) {
}
}
...
好吧,所以试图用代码重现您想要实现的功能,但立即意识到CustomException
只有在类型为RuntimeException
时才有效。原因是您希望在运行时和另一个线程中抛出异常。
下面的代码显示了该异常的简单实现。请记住,并非所有的RuntimeException都会停止程序。这将在本线程中解释。所以如果你想终止程序,你必须手动停止它。
public class CustomException extends RuntimeException {
public CustomException(String msg) {
super(msg);
// print your exception to the console
// optional: exit the program
System.exit(0);
}
}
我更改了实现的其余部分,这样您就不必再进行递归调用了。我删除了回调方法,而是调用get()
方法,该方法等待请求完成。但是由于我是在一个单独的线程中执行所有这些,所以它应该在后台而不是主线程中运行。
public class Main {
private final AsyncHttpClient httpClient;
private final int[] HTTP_ACCEPTED = new int[]{200, 201, 202};
private final static String ENDPOINT = "https://postman-echo.com/post";
public static void main(String[] args) {
String data = "{message: 'Hello World'}";
Main m = new Main();
m.post(data, 10);
}
public Main() {
httpClient = asyncHttpClient();
}
public void post(final String data, final int retry) {
Runnable runnable = () -> {
int retries = retry;
for (int i = 0; i < retry; i++) {
Request request = httpClient.preparePost(ENDPOINT)
.addHeader("Content-Type", "application/json")
.setBody(data)
.build();
ListenableFuture<Response> responseFuture = httpClient.executeRequest(request);
try {
Response response = responseFuture.get();
int status = response.getStatusCode();
if (ArrayUtils.contains(HTTP_ACCEPTED, status)) {
System.out.println("Successful! Breaking Loop");
break;
} else {
Thread.sleep(10);
}
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
retries--;
}
System.out.println("Remaining retries: " + retries);
if (retries <= 0) {
throw new CustomException("exc");
}
};
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(runnable);
}
}
java prettyprint-override">public void post2(final String data, final int retry) {
Request request = httpClient.preparePost(ENDPOINT)
.addHeader("Content-Type", "application/json")
.setBody(data)
.build();
ListenableFuture<Response> future = httpClient.executeRequest(request);
MyRunnable runnable = new MyRunnable(retry, future, request);
future.addListener(runnable, null);
}
public class MyRunnable implements Runnable {
private int retries;
private ListenableFuture<Response> responseFuture;
private final Request request;
public MyRunnable(int retries, ListenableFuture<Response> future, Request request) {
this.retries = retries;
this.responseFuture = future;
this.request = request;
}
@Override
public void run() {
System.out.println("Remaining retries: " + this.retries);
System.out.println("Thread ID: " + Thread.currentThread().getId());
try {
Response response = responseFuture.get();
int status = response.getStatusCode();
if (ArrayUtils.contains(HTTP_ACCEPTED, status)) {
System.out.println("Success!");
//do something here
} else if (this.retries > 0) {
Thread.sleep(10);
this.execute();
} else {
throw new CustomException("Exception!");
}
} catch (InterruptedException | ExecutionException e) {
this.execute();
}
}
private void execute() {
this.retries -= 1;
this.responseFuture = httpClient.executeRequest(this.request);
this.responseFuture.addListener(this, null);
}
}
问题内容: 我有一个以开头的循环。正常情况下,它可以正常运行,但有时由于网络条件而失败。目前,我已对其进行了设置,以便在失败时,它将在except子句中(继续到的下一个数字)。 我是否可以将相同的数字重新分配给循环并再次执行失败的循环? 问题答案: 做一个内部的for循环,把你的代码中,并突破从只有当你的代码的成功循环。
我有一个异步块: 我可以跟踪成功和失败的结果。但是,是否可以重试整个chain?然后继续重试,直到问题解决?
转换为任务返回委托的异步lambda表达式不能返回值
我有一个调用外部应用程序的Restful服务。这个应用程序使我的服务挂起。因此,当用户调用我的服务时,由于这个外部应用程序,可能需要一个小时。外部应用程序只需几秒钟即可执行。否则,就出了问题。因此,我希望我的服务中的代码最多执行30秒。如果超过30秒,我想停止服务并重新启动它。 以下是我想要的: 我不希望代码每30秒执行一次。我希望能够停止代码执行,并从头重新启动它。 服务内容如下:
Apollo link提供了一个错误处理程序 问题:目前,我们希望在apollo调用期间过期时刷新oauth令牌,并且我们无法在中正确执行异步获取请求。 代码: <代码>初始化阿波罗客户端。js 发生的情况是: 初始图形QL查询运行并因未经授权而失败 执行的函数。 刷新令牌的promise已执行。 再次执行的函数?? 刷新令牌的promise完成。 返回初始的graph QL查询结果,其数据为 在
我将JBoss EAP 6.3应用服务器与JDG 6.3.1(使用Infinispan 6.1.2)结合使用,这两个实例都运行在同一个虚拟机上,连接协议是Hot Rod。 如果由于任何原因无法访问JDG,我希望EAP上EJB应用程序中使用的Hot Rod客户端捕捉HotRodClientException,并直接继续进行数据库调用。这可以正常工作,但RemoteCacheManager中的重试次数