Vertx Future 异常处理
Vertx Future 异常处理
异常发生
在使用Vertx进行开发的时候,必不可免使用Future异步编程框架。通过Future的 compose ,可以轻松实现不同异步任务的组合。
但是在每个异步任务的处理过程中,异常的处理是开发者不得不考虑和头疼的问题。无法预知的中断会导致某次任务突然停止在某个阶段。下面是Future代码Demo还原:
private Promise<String> getResponse() {
Promise<String> promise = Promise.promise();
int[] i = new int[1];
LOGGER.info(" throw exception {}", i[2]);
promise.complete("success");
return promise;
}
接口Demo如下
// This handler gets called for each request that arrives on the server
HttpServerResponse response = request.response();
Promise<String> promise = getResponse();
response.putHeader("content-type", "text/plain");
promise.future().setHandler(result -> {
LOGGER.info("result status is {}", result.succeeded());
});
// Write to the response and end it
response.end("Hello World!");
该异常 ArrayIndexOutOfBoundsException 会阻断程序的进行,服务永远不会返回Hello World给客户端。

异常导致后续业务中断
上述demo的异步接口在执行的时候,为什么会导致后面的response.end.... 无法执行。是因为这个异步接口执行过快,在这个线程内执行到了异常,来不及执行response.end方法,就已经失败了。下面Demo演示
private Promise<String> getResponse() {
Promise<String> promise = Promise.promise();
int[] i = new int[1];
// 为了避免接口正常返回业务逻辑执行,设置异常延迟执行
vertx.setTimer(5000, ar -> {
// 此时 异步接口开始输出返回结果
promise.fail("error");
LOGGER.info(" throw exception {}", i[2]);
});
return promise;
}
通过实测当使用无返回值的代码时,接口顺利返回了,同时异步接口一直在等待执行结果输出,说明后续业务逻辑正常执行,异步接口一直在等待。这个是符合逻辑。
private Promise<String> getResponse() {
Promise<String> promise = Promise.promise();
int[] i = new int[1];
// LOGGER.info(" throw exception {}", i[2]);
// 始终不返回执行结果
// promise.complete();
return promise;
}
异常导致compose关联业务无法继续执行
在业务依赖的情况下,比如上面的结果需要被后面的业务使用,这时候就需要去处理异常了。但是感觉每个正常业务逻辑上都写这种Cache异常处理很挫。
这时候发现Vertx提供的阻塞执行代码 executeBlocking 中抛出了异常,但是异步并未中断,而且成功返回了异常了。
vertx.executeBlocking(ar -> {
int[] i = new int[1];
LOGGER.info(" throw exception {}", i[2]);
ar.complete("finish");
}, ar -> {
LOGGER.info("result status is {}, result is {}", ar.succeeded(), ar.result());
});
输出日志如下:
[20:51:36:262] [vert.x-eventloop-thread-0][INFO] - com.vertx.verticle.WebVerticle.lambda$start$2(WebVerticle.java:36) - response to client request
[20:51:36:267] [vert.x-eventloop-thread-0][INFO] - com.vertx.verticle.WebVerticle.lambda$null$1(WebVerticle.java:34) - result status is false, result is null
可以看到,异步已经执行结束,并且结果为false。分析追踪Vertx的executeBlocking 的源代码可以发现他调用了 ContextImpl类的executeBlocking方法。摘选关键代码并添加注释如下:
// blockingCodeHandler 对应上面的业务代码
// resultHandler 对应业务代码执行的结果处理
<T> void executeBlocking(Handler<Promise<T>> blockingCodeHandler,
Handler<AsyncResult<T>> resultHandler) {
Promise<T> promise = Promise.promise();
// 此处代码捕获了所有可抛的异常,一旦有异常产生,就由框架对业务代码返回配置
try {
blockingCodeHandler.handle(promise);
} catch (Throwable e) {
promise.tryFail(e);
}
Future<T> res = promise.future();
res.setHandler(ar -> {
if (resultHandler != null) {
runOnContext(v -> resultHandler.handle(ar));
} else if (ar.failed()) {
// 如果用户未指定异常处理并且执行失败,打印异常
reportException(ar.cause());
}
});
}
学习官方的代码后,发现对业务异常也没有好的实现。后面在个人的业务实现的时候可以考虑提供异步接口实现。毕竟异常一旦抛出,后面全部中断,业务很难进行定位。
Vertx Future 异常处理的更多相关文章
- vertx的Future设计
异步痛点 1.回调地狱(CallBack hell) ; 解决方式 Promise 或 Future 2.执行异步后的结果如何回调currentThread ; 解决方式 Context 设计 3.如 ...
- Callable与Future、FutureTask的学习 & ExecutorServer 与 CompletionService 学习 & Java异常处理-重要
Callable是Java里面与Runnable经常放在一起说的接口. Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务 ...
- vertx verticle
以下内容为随手记的,若看客不知鄙人所云,还请原谅则个.............. 公司用的vertx,在国内,这还是款比较年轻的框架,你也可以把他当做一个工具,官网上的说法是: Vert.x is a ...
- vertx简单客户端创建
import java.util.HashMap;import java.util.Map; import com.yunva.vertx.test.vertproject.util.JsonUtil ...
- Scalaz(44)- concurrency :scalaz Future,尚不完整的多线程类型
scala已经配备了自身的Future类.我们先举个例子来了解scala Future的具体操作: import scala.concurrent._ import ExecutionContext. ...
- Oracle PL/SQL 非预定义异常、自定义异常处理、RAISE_APPLICATION_ERROR
抛出异常 Oracle有三种类型的异常错误: 1. 预定义(Predefined)异常 ORACLE预定义的异常情况大约有24个.对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发. ...
- folly教程系列之:future/promise
attension:本文严禁转载. 一.前言 promise/future是一个非常重要的异步编程模型,它可以让我们摆脱传统的回调陷阱,从而使用更加优雅.清晰的方式进行异步编程.c++11中 ...
- Java子线程中的异常处理(通用)
在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally ...代码块就可以了.那么,在并发情况下,比如在父线程中启动了子线程,如何正确捕获子线程中的异常,从而进行相 ...
- CompletableFuture CompletableFuture.supplyAsync 异常处理
CompletableFuture 异常处理completeExceptionally可以把异常抛到主线程 /** * User: laizhenwei * Date: 2018-01-30 Time ...
随机推荐
- 初探Electron,从入门到实践
本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 在开始之前,我想您一定会有这样的困惑:标题里的Electron ...
- wait()、notify()方法原理,以及使用注意事项
wait.notify原理 在前面以经说到对象锁的本质,实际上是对象头的一个监视器锁的数据结构.这个结构如下: (图片来源于网络) 几个线程一起竞争对象的锁(enter),只有一个能成功(acquir ...
- (一)LinkedList集合解析及手写集合
一.LinkedList集合特点 问题 结 论 LinkedList是否允许空 允许 LinkedList是否允许重复数据 允许 LinkedList是否有序 有序 LinkedList是否 ...
- UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 16: illegal multibyte sequence
报错 UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 16: illegal multibyte sequence ...
- P2766 最长不下降子序列问题 网络流
link:https://www.luogu.org/problemnew/show/P2766 题意 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的 ...
- HDU dp递推 母牛的故事 *
母牛的故事 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- 【Offer】[67] 【把字符串转换成整数】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能 ...
- python中列表,数字,字符串函数总结
列表list: arr = [] 1.可以定义空列表 2.可以定义只有一个元素的列表 3.元素可以是任意类型 arr.append('abc')末尾添加 arr.insert(index,objec) ...
- 微服务时代之自定义archetype(模板/骨架/脚手架)
1. 场景描述 (1)随着微服务越来越常见,一个大的项目会被拆分成多个小的微服务,jar包以及jar之间的版本冲突问题,变得越来越常见,如何保持整体微服务群jar及版本统一,也变成更加重要了,mave ...
- 解开Batch Normalization的神秘面纱
停更博客好长一段时间了,其实并不是没写了,而是转而做笔记了,但是发现做笔记其实印象无法更深刻,因此决定继续以写博客来记录或者复习巩固所学的知识,与此同时跟大家分享下自己对深度学习或者机器学习相关的知识 ...