You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by GitBox <gi...@apache.org> on 2021/05/12 13:04:53 UTC

[GitHub] [skywalking] stateIs0 edited a comment on issue #6932: Make SkyWalking as a core component when doing mock traffic testing on product env.

stateIs0 edited a comment on issue #6932:
URL: https://github.com/apache/skywalking/issues/6932#issuecomment-839755006


   @wu-sheng 
   First of all, I'm not sure what your solution with ShardingSphere is, but my feeling is that it would be better not to introduce other components.
   Then, let me talk briefly about our current solution:
   1. Collect all plug-ins with class as key.
   2. When calling a method, find an interceptor matching the method according to method.
   3. Find these interceptors and build a chain of filters. And cache the filter chain.
   4. Make a call to the filter chain
   
   The pseudocode is as follows:
   
   ```Java
   @RuntimeType
   public Object trace(@This Object obj,
                           @AllArguments Object[] allArguments,
                           @Origin Method method,
                           @SuperCall Callable<?> zuper) throws Throwable {
           if (cache.get(method) != null) {
               return cache.get(method).invoke(new ParamModel(obj, allArguments, method, zuper));
           }
           List<Builder.Interceptor> interceptorList = new ArrayList<>();
           for (Builder.Interceptor interceptor : interceptors) {
               List<ElementMatcher<MethodDescription>> matches = interceptor.matches();
               for (ElementMatcher<MethodDescription> match : matches) {
                   // 找到能够匹配这个方法的拦截器.
                   if (match.matches(new MethodDescription.ForLoadedMethod(method))) {
                       interceptorList.add(interceptor);
                   }
               }
           }
           // 排序
           interceptorList.sort(Comparator.comparingInt(Builder.Interceptor::order));
           List<ChainFactory.Filter<Object, ParamModel>> list = new ArrayList<>();
           // 将每个拦截器用 filter 包装起来
           for (Builder.Interceptor interceptor : interceptorList) {
               list.add((target, arg) -> {
                   // before
                   interceptor.beforeMethod(arg.obj, arg.method, arg.allArguments, method.getParameterTypes(), new MethodInterceptResult());
                   Object result = null;
                   try {
                       // 下个过滤器进行调用
                       result = target.invoke(arg);
                   } catch (Throwable throwable) {
                       interceptor.handleMethodException(arg.obj, arg.method, arg.allArguments, method.getParameterTypes(), throwable);
                   }
                   // after
                   interceptor.afterMethod(arg.obj, arg.method, arg.allArguments, method.getParameterTypes(), result);
                   return result;
               });
           }
   
           //  构建过滤器链, 并添加尾部节点. 尾部节点直接调用目标方法.
           ChainFactory.Invoker<Object, ParamModel> chain = ChainFactory.build(list, paramModel -> paramModel.zuper.call());
   
           // 发起调用.
           Object result = chain.invoke(new ParamModel(obj, allArguments, method, zuper));
           return result;
   }
   
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org