Skip to content

Commit

Permalink
Support extensible slot chain builder using SPI mechanism (#145)
Browse files Browse the repository at this point in the history
- Support extensible `SlotChainBuilder` using SPI mechanism
- Add a `SlotChainProvider` to load slot chain builder and create new slot chains

Signed-off-by: Eric Zhao <[email protected]>
  • Loading branch information
sczyh30 authored Sep 12, 2018
1 parent d142a07 commit ca2f4d9
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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;
Expand Down Expand Up @@ -133,7 +134,7 @@ private ProcessorSlot<Object> lookProcessChain(ResourceWrapper resourceWrapper)
return null;
}

chain = Env.slotsChainbuilder.build();
chain = SlotChainProvider.newSlotChain();
Map<ResourceWrapper, ProcessorSlotChain> newMap = new HashMap<ResourceWrapper, ProcessorSlotChain>(
chainMap.size() + 1);
newMap.putAll(chainMap);
Expand Down
3 changes: 0 additions & 3 deletions sentinel-core/src/main/java/com/alibaba/csp/sentinel/Env.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@
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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Original file line number Diff line number Diff line change
@@ -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() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

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;
Expand All @@ -32,7 +33,7 @@
* @author qinan.qn
* @author leyou
*/
public class DefaultSlotsChainBuilder implements SlotsChainBuilder {
public class DefaultSlotChainBuilder implements SlotChainBuilder {

@Override
public ProcessorSlotChain build() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Default slot chain builder
com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder

0 comments on commit ca2f4d9

Please sign in to comment.