Soul网关-day18

Soul网关-day18

Soul网关-hystrix插件(四)

​ 突然得知这是最后一天的源码任务了,其实还可以继续写因为感觉我Soul源码解读还差好多…

​ 昨天解析到了DefaultSoulPluginChain,那么今天就来详细解读一下这个类相关的东西把;首先这个类是SoulWebHandler的子类。

/**
 * This is web handler request starter.
 *
**/
public final class SoulWebHandler implements WebHandler {
    private final List<SoulPlugin> plugins;

    private final Scheduler scheduler;
    //...省略构造方法,构造方法主要传入了SoulPlugin的list
    
    /**
     * Handle the web server exchange.
     *
     * @param exchange the current server exchange
     * @return {@code Mono<Void>} to indicate when request handling is complete
     */
        @Override
    public Mono<Void> handle(@NonNull final ServerWebExchange exchange) {
        MetricsTrackerFacade.getInstance().counterInc(MetricsLabelEnum.REQUEST_TOTAL.getName());
        Optional<HistogramMetricsTrackerDelegate> startTimer = MetricsTrackerFacade.getInstance().histogramStartTimer(MetricsLabelEnum.REQUEST_LATENCY.getName());
        return new DefaultSoulPluginChain(plugins).execute(exchange).subscribeOn(scheduler)
                .doOnSuccess(t -> startTimer.ifPresent(time -> MetricsTrackerFacade.getInstance().histogramObserveDuration(time)));
    }
}

看注释,这个类是一个web handler请求的starter,里面定义维护了一个SoulPlugin的List,还有一个定时任务;其中还有一个handle的方法,这个handle方法是web server exchange的处理器,输入的参数是当前服务的exchange,输出的参数是Mono,这个返回值是表示这个处理已经完成。

而它的内部类DefaultSoulPluginChain虽然比较短小精悍,但是确实是比较有意思的:

    private static class DefaultSoulPluginChain implements SoulPluginChain {

        private int index;

        private final List<SoulPlugin> plugins;

        /**
         * Instantiates a new Default soul plugin chain.
         *
         * @param plugins the plugins
         */
        DefaultSoulPluginChain(final List<SoulPlugin> plugins) {
            this.plugins = plugins;
        }

        /**
         * Delegate to the next {@code WebFilter} in the chain.
         *
         * @param exchange the current server exchange
         * @return {@code Mono<Void>} to indicate when request handling is complete
         */
        @Override
        public Mono<Void> execute(final ServerWebExchange exchange) {
            return Mono.defer(() -> {
                if (this.index < plugins.size()) {
                    SoulPlugin plugin = plugins.get(this.index++);
                    Boolean skip = plugin.skip(exchange);
                    if (skip) {
                        return this.execute(exchange);
                    }
                    return plugin.execute(exchange, this);
                }
                return Mono.empty();
            });
        }
    }

这里看到这个内部类中只有一个execute方法,这个方法用到了reactor形式的api:Mono.detfer,这个是用来做什么呢?上网查了下资料,是这样说的:Mono.just会在声明阶段构造Date对象,只创建一次;但是Mono.defer却是在subscribe阶段才会创建对应的Date对象,每次调用subscribe方法都会创建Date对象。

那么这个方法的作用就是:每次调用execute方法的时候,都会判断下当前所在的index是否已经超过了我们定义的插件长度,如果没有,就把PluginList中index位置的插件取出来,然后index自增1。判断这个插件是否需要跳过这个exchange。如果要跳过,则直接进入取下一个Index的流程,否则就调用plugin的execute方法,为了让pluginChain传递下去,则需要把当前实例同时传递到plugin的execute方法参数中。

如果index超过了插件列表的长度,则返回一个空结果。


版权声明:本文为qq_21364629原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。