refactor: Make the ProcessorSlot itself as SPI and deprecate legacy slot chain builder (#411)
* Make slots loaded by SPI, mark all slots with @SpiOrder from -10000 to -1000, improve comment * Reserve gateway and param slot chain builder (just extends DefaultSlotChainBuilder) and mark them as @Deprecated
This commit is contained in:
parent
5885add4c5
commit
be4d058bf8
|
|
@ -27,11 +27,13 @@ import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowChecker;
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
@Deprecated
|
||||
public class GatewaySlotChainBuilder extends DefaultSlotChainBuilder {
|
||||
|
||||
@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());
|
||||
|
||||
return chain;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
com.alibaba.csp.sentinel.adapter.gateway.common.slot.GatewayFlowSlot
|
||||
|
|
@ -1 +0,0 @@
|
|||
com.alibaba.csp.sentinel.adapter.gateway.common.slot.GatewaySlotChainBuilder
|
||||
|
|
@ -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}.
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.alibaba.csp.sentinel.node.DefaultNode;
|
|||
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.
|
||||
|
|
@ -30,6 +31,7 @@ import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
|||
* @author leyou
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
@SpiOrder(-6000)
|
||||
public class AuthoritySlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ import com.alibaba.csp.sentinel.node.DefaultNode;
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -136,6 +137,7 @@ import com.alibaba.csp.sentinel.util.function.Function;
|
|||
* @author jialiang.linjl
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
@SpiOrder(-2000)
|
||||
public class FlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
|
||||
private final FlowRuleChecker checker;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
|
|||
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>
|
||||
|
|
@ -44,6 +45,7 @@ import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
|||
*
|
||||
* @author jialiang.linjl
|
||||
*/
|
||||
@SpiOrder(-9000)
|
||||
public class ClusterBuilderSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,11 +21,13 @@ 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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.alibaba.csp.sentinel.node.DefaultNode;
|
|||
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;
|
||||
|
|
@ -122,6 +123,7 @@ import java.util.Map;
|
|||
* @see EntranceNode
|
||||
* @see ContextUtil
|
||||
*/
|
||||
@SpiOrder(-10000)
|
||||
public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.alibaba.csp.sentinel.config.SentinelConfig;
|
|||
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;
|
||||
|
|
@ -47,6 +48,7 @@ import com.alibaba.csp.sentinel.slots.block.BlockException;
|
|||
* @author jialiang.linjl
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
@SpiOrder(-7000)
|
||||
public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.alibaba.csp.sentinel.node.DefaultNode;
|
|||
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.
|
||||
|
|
@ -27,6 +28,7 @@ import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
|||
* @author jialiang.linjl
|
||||
* @author leyou
|
||||
*/
|
||||
@SpiOrder(-5000)
|
||||
public class SystemSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ public final class SpiLoader {
|
|||
}
|
||||
|
||||
/**
|
||||
* Load and sorted SPI instance list.
|
||||
* Load the SPI instance list for provided SPI interface.
|
||||
*
|
||||
* @param clazz class of the SPI
|
||||
|
|
@ -161,6 +162,8 @@ public final class SpiLoader {
|
|||
/**
|
||||
* 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
|
||||
|
|
@ -196,6 +199,41 @@ public final class SpiLoader {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.slots;
|
||||
|
||||
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
|
||||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain;
|
||||
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 org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test cases for {@link DefaultSlotChainBuilder}.
|
||||
*
|
||||
* @author cdfive
|
||||
*/
|
||||
public class DefaultSlotChainBuilderTest {
|
||||
|
||||
@Test
|
||||
public void testBuild() {
|
||||
DefaultSlotChainBuilder builder = new DefaultSlotChainBuilder();
|
||||
ProcessorSlotChain slotChain = builder.build();
|
||||
assertNotNull(slotChain);
|
||||
|
||||
// Verify the order of slot
|
||||
AbstractLinkedProcessorSlot<?> next = slotChain.getNext();
|
||||
assertTrue(next instanceof NodeSelectorSlot);
|
||||
|
||||
// Store the first NodeSelectorSlot instance
|
||||
NodeSelectorSlot nodeSelectorSlot = (NodeSelectorSlot) next;
|
||||
|
||||
next = next.getNext();
|
||||
assertTrue(next instanceof ClusterBuilderSlot);
|
||||
|
||||
next = next.getNext();
|
||||
assertTrue(next instanceof LogSlot);
|
||||
|
||||
next = next.getNext();
|
||||
assertTrue(next instanceof StatisticSlot);
|
||||
|
||||
next = next.getNext();
|
||||
assertTrue(next instanceof AuthoritySlot);
|
||||
|
||||
next = next.getNext();
|
||||
assertTrue(next instanceof SystemSlot);
|
||||
|
||||
next = next.getNext();
|
||||
assertTrue(next instanceof FlowSlot);
|
||||
|
||||
next = next.getNext();
|
||||
assertTrue(next instanceof DegradeSlot);
|
||||
|
||||
next = next.getNext();
|
||||
assertNull(next);
|
||||
|
||||
// Build again to verify different instances
|
||||
ProcessorSlotChain slotChain2 = builder.build();
|
||||
assertNotNull(slotChain2);
|
||||
// Verify the two ProcessorSlotChain instances are different
|
||||
assertNotSame(slotChain, slotChain2);
|
||||
|
||||
next = slotChain2.getNext();
|
||||
assertTrue(next instanceof NodeSelectorSlot);
|
||||
// Store the second NodeSelectorSlot instance
|
||||
NodeSelectorSlot nodeSelectorSlot2 = (NodeSelectorSlot) next;
|
||||
// Verify the two NodeSelectorSlot instances are different
|
||||
assertNotSame(nodeSelectorSlot, nodeSelectorSlot2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.util;
|
||||
|
||||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
|
||||
import com.alibaba.csp.sentinel.slotchain.SlotChainBuilder;
|
||||
import com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder;
|
||||
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 org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test cases for {@link SpiLoader}.
|
||||
*
|
||||
* @author cdfive
|
||||
*/
|
||||
public class SpiLoaderTest {
|
||||
|
||||
@Test
|
||||
public void testLoadFirstInstance() {
|
||||
ProcessorSlot processorSlot = SpiLoader.loadFirstInstance(ProcessorSlot.class);
|
||||
assertNotNull(processorSlot);
|
||||
|
||||
SlotChainBuilder slotChainBuilder = SpiLoader.loadFirstInstance(SlotChainBuilder.class);
|
||||
assertNotNull(slotChainBuilder);
|
||||
assertTrue(slotChainBuilder instanceof DefaultSlotChainBuilder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadHighestPriorityInstance() {
|
||||
ProcessorSlot processorSlot = SpiLoader.loadHighestPriorityInstance(ProcessorSlot.class);
|
||||
assertNotNull(processorSlot);
|
||||
|
||||
// NodeSelectorSlot is highest order with @SpiOrder(-9000), among all slots
|
||||
assertTrue(processorSlot instanceof NodeSelectorSlot);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadInstanceList() {
|
||||
List<ProcessorSlot> slots = SpiLoader.loadInstanceList(ProcessorSlot.class);
|
||||
assertNotNull(slots);
|
||||
|
||||
// Total 8 default slot in sentinel-core
|
||||
assertEquals(8, slots.size());
|
||||
|
||||
// Store the first slot of slots
|
||||
ProcessorSlot firstSlot = slots.get(0);
|
||||
|
||||
// Call loadInstanceList again
|
||||
List<ProcessorSlot> slots2 = SpiLoader.loadInstanceList(ProcessorSlot.class);
|
||||
assertNotSame(slots, slots2);
|
||||
|
||||
// Store the first slot of slots
|
||||
ProcessorSlot firstSlot2 = slots2.get(0);
|
||||
|
||||
// As SERVICE_LOADER_MAP in SpiLoader cached the instance, so they're same instances
|
||||
assertSame(firstSlot, firstSlot2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadInstanceListSorted() {
|
||||
List<ProcessorSlot> sortedSlots = SpiLoader.loadInstanceListSorted(ProcessorSlot.class);
|
||||
assertNotNull(sortedSlots);
|
||||
|
||||
// Total 8 default slot in sentinel-core
|
||||
assertEquals(8, sortedSlots.size());
|
||||
|
||||
// Verify the order of slot
|
||||
int index = 0;
|
||||
assertTrue(sortedSlots.get(index++) instanceof NodeSelectorSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof ClusterBuilderSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof LogSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof StatisticSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof AuthoritySlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof SystemSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof FlowSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof DegradeSlot);
|
||||
|
||||
// Verify each call return different instances
|
||||
List<ProcessorSlot> sortedSlots2 = SpiLoader.loadInstanceListSorted(ProcessorSlot.class);
|
||||
assertNotSame(sortedSlots, sortedSlots2);
|
||||
assertEquals(sortedSlots.size(), sortedSlots2.size());
|
||||
for (int i = 0; i < sortedSlots.size(); i++) {
|
||||
ProcessorSlot slot = sortedSlots.get(i);
|
||||
ProcessorSlot slot2 = sortedSlots2.get(i);
|
||||
assertEquals(slot.getClass(), slot2.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadDifferentInstanceListSorted() {
|
||||
List<ProcessorSlot> sortedSlots = SpiLoader.loadInstanceListSorted(ProcessorSlot.class);
|
||||
assertNotNull(sortedSlots);
|
||||
|
||||
// Total 8 default slot in sentinel-core
|
||||
assertEquals(8, sortedSlots.size());
|
||||
|
||||
// Verify the order of slot
|
||||
int index = 0;
|
||||
assertTrue(sortedSlots.get(index++) instanceof NodeSelectorSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof ClusterBuilderSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof LogSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof StatisticSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof AuthoritySlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof SystemSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof FlowSlot);
|
||||
assertTrue(sortedSlots.get(index++) instanceof DegradeSlot);
|
||||
|
||||
// Verify each call return different instances
|
||||
List<ProcessorSlot> sortedSlots2 = SpiLoader.loadDifferentInstanceListSorted(ProcessorSlot.class);
|
||||
assertNotSame(sortedSlots, sortedSlots2);
|
||||
assertEquals(sortedSlots.size(), sortedSlots2.size());
|
||||
for (int i = 0; i < sortedSlots.size(); i++) {
|
||||
ProcessorSlot slot = sortedSlots.get(i);
|
||||
ProcessorSlot slot2 = sortedSlots2.get(i);
|
||||
assertEquals(slot.getClass(), slot2.getClass());
|
||||
|
||||
// Verify the instances are different
|
||||
assertNotSame(slot, slot2);
|
||||
assertNotEquals(slot, slot2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,38 +15,18 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.slots;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
* @since 0.2.0
|
||||
*
|
||||
* @deprecated since 1.7.2, we can use @SpiOrder(-3000) to adjust the order of {@link ParamFlowSlot},
|
||||
* this class is reserved for compatibility with older versions.
|
||||
* @see ParamFlowSlot
|
||||
* @see DefaultSlotChainBuilder
|
||||
*/
|
||||
public class HotParamSlotChainBuilder implements SlotChainBuilder {
|
||||
@Deprecated
|
||||
public class HotParamSlotChainBuilder extends DefaultSlotChainBuilder {
|
||||
|
||||
@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 ParamFlowSlot());
|
||||
chain.addLast(new FlowSlot());
|
||||
chain.addLast(new DegradeSlot());
|
||||
|
||||
return chain;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.slots.block.flow.param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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 java.util.List;
|
||||
|
||||
/**
|
||||
* A processor slot that is responsible for flow control by frequent ("hot spot") parameters.
|
||||
|
|
@ -30,6 +31,7 @@ import com.alibaba.csp.sentinel.slots.block.BlockException;
|
|||
* @author Eric Zhao
|
||||
* @since 0.2.0
|
||||
*/
|
||||
@SpiOrder(-3000)
|
||||
public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowSlot
|
||||
|
|
@ -1 +0,0 @@
|
|||
com.alibaba.csp.sentinel.slots.HotParamSlotChainBuilder
|
||||
Loading…
Reference in New Issue