fn) {this.responseFuture = this.responseFuture.whenComplete((v, t) -> {beforeContext.accept(v, t);fn.accept(v, t);afterContext.accept(v, t);});return this;}@Overridepublic Result invoke(Invocation invocation) throws RpcException {Result asyncResult;try {interceptor.before(next, invocation);asyncResult = interceptor.intercept(next, invocation);} catch (Exception e) {// onError callbackif (interceptor instanceof ClusterInterceptor.Listener) {ClusterInterceptor.Listener listener = (ClusterInterceptor.Listener) interceptor;listener.onError(e, clusterInvoker, invocation);}throw e;} finally {interceptor.after(next, invocation);}return asyncResult.whenCompleteWithContext((r, t) -> {// onResponse callbackif (interceptor instanceof ClusterInterceptor.Listener) {ClusterInterceptor.Listener listener = (ClusterInterceptor.Listener) interceptor;if (t == null) {listener.onMessage(r, clusterInvoker, invocation);} else {listener.onError(t, clusterInvoker, invocation);}}});}看不懂代码不要怕 , 肥朝大白话解释一下 。 你就想象一个Dubbo异步场景 , Dubbo异步回调结果的时候 , 是会开启一个新的线程 , 那么 , 这个回调就和当初请求不在一个线程里面了 , 因此这个回调线程是拿不到当初请求的RpcContext 。 但是我们清空RpcContext是需要在一次请求结束的时候 , 也就是说 , 虽然异步回调是另外一个线程了 , 但是我们仍然需要拿到当初请求时候的RpcContext来走Filter , 做清空等操作 。 上面那段代码就是做 , 切换线程怎么拿回之前的RpcContext 。
听完上面的分析 , 你是不是明白了点啥?新线程 , 还能拿到旧的RpcContext 。 那么 , 有这么一个场景 , 我们在通过提供者方法中 , 发起两个异步请求 , 第一个请求走Filter的onResponse(响应结果)的时候 , 我们如果在Filter做RpcContext.getContext().setAttachment操作 , 第二个请求又正好发起 , 而发起又会经历putAll这步骤 , 就会出现这个并发修改异常 。 于是乎 , 真相大白!
拓展性思考真相大白就结束了?熟悉肥朝的粉丝都知道 , 我们遇到问题 , 要尽量压榨问题的全部价值!比如 , 你说不要在拦截器中onResponse方法中用RpcContext.getContext().setAttachment这样的操作 , 但是我们确实有类似需要 , 那到底要怎么写代码又不说 , 你这样叫我怎么给你转发文章!
文章插图
我们要知道怎么正确写代码 , 那直接去抄Dubbo其他拦截器的代码不就知道了?比如
@Activate(group = PROVIDER, order = -10000)public class ContextFilter implements Filter, Filter.Listener {@Overridepublic void onResponse(Result appResponse, Invoker> invoker, Invocation invocation) {// pass attachments to resultappResponse.addObjectAttachments(RpcContext.getServerContext().getObjectAttachments());}}我们很明显看到 , 你熟悉一下appResponse的api和他的作用 , 就很容易知道 , 有类似需求 , 代码应该怎么写了 。 我光告诉你怎么写代码没用啊 , 我要告诉你 , 遇到问题 , 怎么去抄正确代码 , 让你任何时候 , 都有得cao!
推荐阅读
-
晓东游戏君|阿离,貂蝉新动作领取,李小龙皮肤值不值得玩?看局内建模就知道
-
延迟退休实施原则 延迟退休实施原则公布!70/80/90后退休年龄清楚了
-
-
-
-
环球网| 美国白人男子遭多名黑人扔鞭炮,部分击中脸部,
-
-
詹姆斯·哈登|王炸80+20+16!哈登爆锤独行侠,考文顿绝命5分,威少也将功补过
-
婚姻经营|《我们离婚吧》揭露的扎心真相:冷暴力,远超过婚姻中的任何劫难
-
附:口碑最好有机奶粉品牌排行榜 2020有机牛奶哪个牌子好
-
明星|杨紫方发律师函维权上热搜 被恶意造谣辱骂:网友支持维护网络环境和平
-
-
原神|端游TAPTAP评分4.0,手游评分6.1,《原神》真的这么差?
-
文娱马后炮▲Kuro:T1战是BP的胜利 我们绝不是排名倒数的队伍,KT
-
-
-
光明网|反诈宣传入心入脑 女大学生及时醒悟求助警方
-
-
-
『生理慧医师』民间的3个小偏方,专克关节炎症,老人易患风湿性关节炎