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超过了插件列表的长度,则返回一个空结果。