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!
推荐阅读
-
「熊黛林」被嘲7年全靠郭富城上位,今成百亿阔太:熊黛林,你怎么做到的?
-
|开局即是高潮,部部让人血脉紧张,这10部电影百看不厌
-
标准:汽车市场加快分化 “国六”时代真真切切地来了
-
仙剑奇侠传|128元!国民级IP大作《仙剑奇侠传七》销量首曝:去年卖了60万套
-
『科技生活快报』伊拉克安全部队:中国石油企业在伊遭到火箭弹袭击
-
DNF心情咖啡屋|DNF:女法三觉道具也太香!连透明套都来了,商城36R可拿到
-
邵婷|功勋球员邵婷合同到期离队,首钢不舍仍送上祝福
-
小语谈情|遇到这三种渣男,一定要远离,谁碰上谁倒霉,在生活中
-
庄河市|辽宁庄河:防台风应急响应提升至Ⅰ级,所有客运班线全部停运
-
「朝鲜发现1例新冠肺炎疑似病例」朝鲜发现1例新冠肺炎疑似病例 金正恩严惩边境部队
-
-
-
蒋蒋爱八卦|曾是《灵魂摆渡》的“最美孟婆”,离开了古装造型,却秒变路人脸,原创
-
-
-
-
『娱乐嘉许』关乎全国每位储户的利益!存款利息被叫停?,央行发布最新通知
-
中国海军|火力全开!中国海军护航编队亚丁湾实弹练兵
-
范伟|离开赵本山,60岁范伟“挑大梁”演东北喜剧,开播就是榜单冠军
-