* 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 @Deprecatedmaster
@@ -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 { | |||
@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 { | |||
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 { | |||
@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()); | |||
@Deprecated | |||
public class HotParamSlotChainBuilder extends DefaultSlotChainBuilder { | |||
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 |