Browse Source

Support extensible slot chain builder using SPI mechanism (#145)

- 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
Eric Zhao GitHub 6 years ago
parent
commit
ca2f4d9fae
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 11 deletions
  1. +2
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtSph.java
  2. +0
    -3
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/Env.java
  3. +7
    -6
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slotchain/SlotChainBuilder.java
  4. +78
    -0
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slotchain/SlotChainProvider.java
  5. +2
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilder.java
  6. +2
    -0
      sentinel-core/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.slotchain.SlotChainBuilder

+ 2
- 1
sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtSph.java View File

@@ -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);


+ 0
- 3
sentinel-core/src/main/java/com/alibaba/csp/sentinel/Env.java View File

@@ -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();



sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/SlotsChainBuilder.java → sentinel-core/src/main/java/com/alibaba/csp/sentinel/slotchain/SlotChainBuilder.java View File

@@ -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();
}

+ 78
- 0
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slotchain/SlotChainProvider.java View File

@@ -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() {}
}

sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/DefaultSlotsChainBuilder.java → sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilder.java View File

@@ -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() {

+ 2
- 0
sentinel-core/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.slotchain.SlotChainBuilder View File

@@ -0,0 +1,2 @@
# Default slot chain builder
com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder

Loading…
Cancel
Save