Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the slot as the SPI interface and add a @Order annotation for define slot order #411

Merged
merged 8 commits into from
Mar 26, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParameterMetricStorage;
import com.alibaba.csp.sentinel.spi.SpiOrder;

/**
* @author Eric Zhao
* @since 1.6.1
*/
@SpiOrder(-4000)
public class GatewayFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,18 @@
*/
package com.alibaba.csp.sentinel.adapter.gateway.common.slot;

import com.alibaba.csp.sentinel.slotchain.DefaultProcessorSlotChain;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain;
import com.alibaba.csp.sentinel.slotchain.SlotChainBuilder;
import com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot;
import com.alibaba.csp.sentinel.slots.block.flow.FlowSlot;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowSlot;
import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
import com.alibaba.csp.sentinel.slots.logger.LogSlot;
import com.alibaba.csp.sentinel.slots.nodeselector.NodeSelectorSlot;
import com.alibaba.csp.sentinel.slots.statistic.StatisticSlot;
import com.alibaba.csp.sentinel.slots.system.SystemSlot;
import com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder;

/**
* @author Eric Zhao
* @since 1.6.1
*
* @deprecated since 1.7.2, we can use @SpiOrder(-4000) to adjust the order of {@link GatewayFlowSlot},
* this class is reserved for compatibility with older versions.
* @see GatewayFlowSlot
* @see DefaultSlotChainBuilder
*/
public class GatewaySlotChainBuilder implements SlotChainBuilder {

@Override
public ProcessorSlotChain build() {
ProcessorSlotChain chain = new DefaultProcessorSlotChain();
// Prepare slot
chain.addLast(new NodeSelectorSlot());
chain.addLast(new ClusterBuilderSlot());
// Stat slot
chain.addLast(new LogSlot());
chain.addLast(new StatisticSlot());
// Rule checking slot
chain.addLast(new AuthoritySlot());
chain.addLast(new SystemSlot());
chain.addLast(new GatewayFlowSlot());

chain.addLast(new ParamFlowSlot());
chain.addLast(new FlowSlot());
chain.addLast(new DegradeSlot());
@Deprecated
public class GatewaySlotChainBuilder extends DefaultSlotChainBuilder {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh if you take my advice keeping an empty legacy one you should make it a real EMPTY one.
According to the new DefaultSlotChainBuilder i think there is no need keeping overriding of build() here, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry for misunderstanding the point.It has been fixed, please check.


return chain;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.alibaba.csp.sentinel.adapter.gateway.common.slot.GatewayFlowSlot

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@
*/
package com.alibaba.csp.sentinel.slots;

import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.DefaultProcessorSlotChain;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain;
import com.alibaba.csp.sentinel.slotchain.SlotChainBuilder;
import com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot;
import com.alibaba.csp.sentinel.slots.block.flow.FlowSlot;
import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
import com.alibaba.csp.sentinel.slots.logger.LogSlot;
import com.alibaba.csp.sentinel.slots.nodeselector.NodeSelectorSlot;
import com.alibaba.csp.sentinel.slots.statistic.StatisticSlot;
import com.alibaba.csp.sentinel.slots.system.SystemSlot;
import com.alibaba.csp.sentinel.util.SpiLoader;

import java.util.List;

/**
* Builder for a default {@link ProcessorSlotChain}.
Expand All @@ -38,16 +36,18 @@ public class DefaultSlotChainBuilder implements SlotChainBuilder {
@Override
public ProcessorSlotChain build() {
ProcessorSlotChain chain = new DefaultProcessorSlotChain();
chain.addLast(new NodeSelectorSlot());
chain.addLast(new ClusterBuilderSlot());
chain.addLast(new LogSlot());
chain.addLast(new StatisticSlot());
chain.addLast(new AuthoritySlot());
chain.addLast(new SystemSlot());
chain.addLast(new FlowSlot());
chain.addLast(new DegradeSlot());

// Note: the instances of ProcessorSlot should be different, since they are not stateless.
List<ProcessorSlot> sortedSlotList = SpiLoader.loadDifferentInstanceListSorted(ProcessorSlot.class);
for (ProcessorSlot slot : sortedSlotList) {
if (!(slot instanceof AbstractLinkedProcessorSlot)) {
RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain");
continue;
}

chain.addLast((AbstractLinkedProcessorSlot<?>) slot);
}

return chain;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.spi.SpiOrder;

/**
* A {@link ProcessorSlot} that dedicates to {@link AuthorityRule} checking.
*
* @author leyou
* @author Eric Zhao
*/
@SpiOrder(-6000)
public class AuthoritySlot extends AbstractLinkedProcessorSlot<DefaultNode> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.spi.SpiOrder;

/**
* A {@link ProcessorSlot} dedicates to {@link DegradeRule} checking.
*
* @author leyou
*/
@SpiOrder(-1000)
public class DegradeSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@
*/
package com.alibaba.csp.sentinel.slots.block.flow;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.alibaba.csp.sentinel.context.Context;
import com.alibaba.csp.sentinel.node.DefaultNode;
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.spi.SpiOrder;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.function.Function;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* <p>
* Combined the runtime statistics collected from the previous
Expand Down Expand Up @@ -136,6 +137,7 @@
* @author jialiang.linjl
* @author Eric Zhao
*/
@SpiOrder(-2000)
public class FlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

private final FlowRuleChecker checker;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
import com.alibaba.csp.sentinel.spi.SpiOrder;

/**
* <p>
Expand All @@ -44,6 +45,7 @@
*
* @author jialiang.linjl
*/
@SpiOrder(-9000)
public class ClusterBuilderSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.spi.SpiOrder;

/**
* A {@link com.alibaba.csp.sentinel.slotchain.ProcessorSlot} that is response for logging block exceptions
* to provide concrete logs for troubleshooting.
*/
@SpiOrder(-8000)
public class LogSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.alibaba.csp.sentinel.node.EntranceNode;
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.spi.SpiOrder;

import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -122,6 +123,7 @@
* @see EntranceNode
* @see ContextUtil
*/
@SpiOrder(-10000)
public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotEntryCallback;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotExitCallback;
import com.alibaba.csp.sentinel.slots.block.flow.PriorityWaitException;
import com.alibaba.csp.sentinel.spi.SpiOrder;
import com.alibaba.csp.sentinel.util.TimeUtil;
import com.alibaba.csp.sentinel.Constants;
import com.alibaba.csp.sentinel.EntryType;
Expand All @@ -47,6 +48,7 @@
* @author jialiang.linjl
* @author Eric Zhao
*/
@SpiOrder(-7000)
public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.spi.SpiOrder;

/**
* A {@link ProcessorSlot} that dedicates to {@link SystemRule} checking.
*
* @author jialiang.linjl
* @author leyou
*/
@SpiOrder(-5000)
public class SystemSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public static <T> T loadHighestPriorityInstance(Class<T> clazz) {
}

/**
* Load and sorted SPI instance list.
* Load the SPI instance list for provided SPI interface.
*
* @param clazz class of the SPI
Expand Down Expand Up @@ -161,6 +162,8 @@ public static <T> List<T> loadInstanceList(Class<T> clazz) {
/**
* Load the sorted SPI instance list for provided SPI interface.
*
* Note: each call return new instances.
*
* @param clazz class of the SPI
* @param <T> SPI type
* @return sorted SPI instance list
Expand Down Expand Up @@ -196,6 +199,41 @@ public static <T> List<T> loadInstanceListSorted(Class<T> clazz) {
}
}

/**
* Load the sorted and different SPI instance list for provided SPI interface.
*
* Note: each call return new instances.
*
* @param clazz class of the SPI
* @param <T> SPI type
* @return sorted and different SPI instance list
* @since 1.7.2
*/
public static <T> List<T> loadDifferentInstanceListSorted(Class<T> clazz) {
try {
// Not use SERVICE_LOADER_MAP, to make sure the instances loaded are different.
ServiceLoader<T> serviceLoader = ServiceLoaderUtil.getServiceLoader(clazz);

List<SpiOrderWrapper<T>> orderWrappers = new ArrayList<>();
for (T spi : serviceLoader) {
int order = SpiOrderResolver.resolveOrder(spi);
// Since SPI is lazy initialized in ServiceLoader, we use online sort algorithm here.
SpiOrderResolver.insertSorted(orderWrappers, spi, order);
RecordLog.info("[SpiLoader] Found {0} SPI: {1} with order " + order, clazz.getSimpleName(),
spi.getClass().getCanonicalName());
}
List<T> list = new ArrayList<>();
for (int i = 0; i < orderWrappers.size(); i++) {
list.add(i, orderWrappers.get(i).spi);
}
return list;
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadDifferentInstanceListSorted failed", t);
t.printStackTrace();
return new ArrayList<>();
}
}

private static class SpiOrderResolver {
private static <T> void insertSorted(List<SpiOrderWrapper<T>> list, T spi, int order) {
int idx = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Sentinel default ProcessorSlots
com.alibaba.csp.sentinel.slots.nodeselector.NodeSelectorSlot
com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot
com.alibaba.csp.sentinel.slots.logger.LogSlot
com.alibaba.csp.sentinel.slots.statistic.StatisticSlot
com.alibaba.csp.sentinel.slots.system.SystemSlot
com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot
com.alibaba.csp.sentinel.slots.block.flow.FlowSlot
com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot
Loading