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!
推荐阅读
-
-
qlv如何转换成为mp4格式?两种方法教你快速转化
-
环境|减持!启迪环境:减持计划数量过半持股5%以上股东桑德集团减持约136万股
-
牛大力@在山坡、草地里,有1种杂草,人称“牛大力”,根系1米长,珍贵
-
-
-
田馥甄|从SHE单飞后的才女,到人人喊打的尴尬存在,田馥甄经历了什么?
-
-
『南方前沿』以色列媒体揭露美国新冠病毒谎言:去年11月就已通知盟友当心
-
翡翠|如何买到有收藏价值的翡翠?翡翠的种水分类,这种可遇不可求
-
-
高职院校|21年铁路局招4W+人,大专起报,这些高职院校毕业生最受青睐
-
「3DMGAME」为何《COD6》高清复刻版不含多人模式?不愿割裂玩家
-
狮子座女生失望了要怎么才能挽回 狮子座男生喜欢什么样的女生
-
洋哥爱生活|念念不忘,朝思暮想,旧梦重拾,前缘回归,爱情失而复得,8月初
-
-
张艺谋终究还是强于贾玲,上映十天《第二十条》成功夺冠
-
-
青核桃皮汁弄手上怎么去掉 青皮核桃的汁弄在手上洗不掉怎么办
-
手指芭蕾|围巾绑头上是种什么时尚?60多岁老太太教这个居然有四十多万粉丝