- Support extensible `SlotChainBuilder` using SPI mechanism - Add a `SlotChainProvider` to load slot chain builder and create new slot chains Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -28,6 +28,7 @@ import com.alibaba.csp.sentinel.slotchain.MethodResourceWrapper; | |||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot; | |||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain; | |||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; | |||
import com.alibaba.csp.sentinel.slotchain.SlotChainProvider; | |||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; | |||
import com.alibaba.csp.sentinel.slots.block.BlockException; | |||
import com.alibaba.csp.sentinel.slots.block.Rule; | |||
@@ -133,7 +134,7 @@ public class CtSph implements Sph { | |||
return null; | |||
} | |||
chain = Env.slotsChainbuilder.build(); | |||
chain = SlotChainProvider.newSlotChain(); | |||
Map<ResourceWrapper, ProcessorSlotChain> newMap = new HashMap<ResourceWrapper, ProcessorSlotChain>( | |||
chainMap.size() + 1); | |||
newMap.putAll(chainMap); | |||
@@ -18,15 +18,12 @@ package com.alibaba.csp.sentinel; | |||
import com.alibaba.csp.sentinel.init.InitExecutor; | |||
import com.alibaba.csp.sentinel.node.DefaultNodeBuilder; | |||
import com.alibaba.csp.sentinel.node.NodeBuilder; | |||
import com.alibaba.csp.sentinel.slots.DefaultSlotsChainBuilder; | |||
import com.alibaba.csp.sentinel.slots.SlotsChainBuilder; | |||
/** | |||
* @author jialiang.linjl | |||
*/ | |||
public class Env { | |||
public static final SlotsChainBuilder slotsChainbuilder = new DefaultSlotsChainBuilder(); | |||
public static final NodeBuilder nodeBuilder = new DefaultNodeBuilder(); | |||
public static final Sph sph = new CtSph(); | |||
@@ -13,20 +13,21 @@ | |||
* 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.ProcessorSlotChain; | |||
package com.alibaba.csp.sentinel.slotchain; | |||
/** | |||
* The builder for processor slot chain. | |||
* | |||
* @author qinan.qn | |||
* @author leyou | |||
* @author Eric Zhao | |||
*/ | |||
public interface SlotsChainBuilder { | |||
public interface SlotChainBuilder { | |||
/** | |||
* Helper method to create processor slot chain. | |||
* Build the processor slot chain. | |||
* | |||
* @return a processor slot that chain some slots together. | |||
* @return a processor slot that chain some slots together | |||
*/ | |||
ProcessorSlotChain build(); | |||
} |
@@ -0,0 +1,78 @@ | |||
/* | |||
* 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.slotchain; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.ServiceLoader; | |||
import com.alibaba.csp.sentinel.log.RecordLog; | |||
import com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder; | |||
/** | |||
* A provider for creating slot chains via resolved slot chain builder SPI. | |||
* | |||
* @author Eric Zhao | |||
* @since 0.2.0 | |||
*/ | |||
public final class SlotChainProvider { | |||
private static volatile SlotChainBuilder builder = null; | |||
private static final ServiceLoader<SlotChainBuilder> LOADER = ServiceLoader.load(SlotChainBuilder.class); | |||
/** | |||
* The load and pick process is not thread-safe, but it's okay since the method should be only invoked | |||
* via {@code lookProcessChain} in {@link com.alibaba.csp.sentinel.CtSph} under lock. | |||
* | |||
* @return new created slot chain | |||
*/ | |||
public static ProcessorSlotChain newSlotChain() { | |||
if (builder != null) { | |||
return builder.build(); | |||
} | |||
resolveSlotChainBuilder(); | |||
if (builder == null) { | |||
RecordLog.warn("[SlotChainProvider] Wrong state when resolving slot chain builder, using default"); | |||
builder = new DefaultSlotChainBuilder(); | |||
} | |||
return builder.build(); | |||
} | |||
private static void resolveSlotChainBuilder() { | |||
List<SlotChainBuilder> list = new ArrayList<SlotChainBuilder>(); | |||
boolean hasOther = false; | |||
for (SlotChainBuilder builder : LOADER) { | |||
if (builder.getClass() != DefaultSlotChainBuilder.class) { | |||
hasOther = true; | |||
list.add(builder); | |||
} | |||
} | |||
if (hasOther) { | |||
builder = list.get(0); | |||
} else { | |||
// No custom builder, using default. | |||
builder = new DefaultSlotChainBuilder(); | |||
} | |||
RecordLog.info("[SlotChainProvider] Global slot chain builder resolved: " | |||
+ builder.getClass().getCanonicalName()); | |||
} | |||
private SlotChainProvider() {} | |||
} |
@@ -17,6 +17,7 @@ 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; | |||
@@ -32,7 +33,7 @@ import com.alibaba.csp.sentinel.slots.system.SystemSlot; | |||
* @author qinan.qn | |||
* @author leyou | |||
*/ | |||
public class DefaultSlotsChainBuilder implements SlotsChainBuilder { | |||
public class DefaultSlotChainBuilder implements SlotChainBuilder { | |||
@Override | |||
public ProcessorSlotChain build() { |
@@ -0,0 +1,2 @@ | |||
# Default slot chain builder | |||
com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder |