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万年薪,三年来却无人应聘
-
老友相伴|平时坚持“2多2少”,或许对肝脏健康有好处,男性日常“养肝”
-
有手就行10.9被凤凰传奇和波比血虐?设计师却说:这是最完美最平衡的版本
-
-
新华网|加强长江干堤和“两湖”湖区堤防巡查防守是当前长江防汛重点任务
-
3男子黄瓜配花生米喝117瓶啤酒:3男子黄瓜配花生米喝117瓶啤酒 商家回应确有此事
-
-
中国青年报|参与消费扶贫 超七成受访者最看重产品质量
-
讲武堂|再击毙阿塞拜疆1名军官4名士兵,幕后原因揭开,亚美尼亚突然出手
-
二小埃米|与郭晶晶共谈育儿,产后身材像少女,35岁吴敏霞嫁CEO
-
-
-
右手网一加为尚未正式发售的 OnePlus Nord 推送首个 OxygenOS 更新
-
「直播吧官方」尤文对伊卡尔迪兴趣有所冷却,意媒:考虑引进米利克
-
车家号“东瀛宝马”,造型运动,操控好,真香,新款马自达6
-
青柠的院子|欧洲最受欢迎思维方法《赢者思维》告诉你:你会成为你想成为的人
-
-
国籍■十年寒窗比不过一纸国籍?教育部出新规:“假外国人”的好日子该结束了
-
法拉利|出必买?法拉利首款SUV官宣:前脸凶狠又“邪恶”
-