This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.2 by this push:
new 5ef3b4fb2e Add dual chain support for state router, prevent update
when invoke (#10691)
5ef3b4fb2e is described below
commit 5ef3b4fb2e6ac387fa3a0927eb11c5bd8cd6bea8
Author: Albumen Kevin <[email protected]>
AuthorDate: Fri Oct 14 10:32:20 2022 +0800
Add dual chain support for state router, prevent update when invoke (#10691)
* Add dual chain support for state router, prevent update when invoke
* Fix uts
---
.../org/apache/dubbo/rpc/cluster/RouterChain.java | 334 +++++----------------
.../{RouterChain.java => SingleRouterChain.java} | 56 ++--
.../cluster/router/state/AbstractStateRouter.java | 9 +-
.../dubbo/rpc/cluster/router/state/BitList.java | 5 +-
.../rpc/cluster/directory/StaticDirectoryTest.java | 2 +-
.../router/condition/ConditionStateRouterTest.java | 44 +--
.../cluster/router/file/FileRouterEngineTest.java | 2 +-
.../router/script/ScriptStateRouterTest.java | 8 +-
.../rpc/cluster/router/tag/TagStateRouterTest.java | 3 +-
.../common/constants/LoggerCodeConstants.java | 5 +
10 files changed, 131 insertions(+), 337 deletions(-)
diff --git
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
index 64246b9ea5..877f16032e 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
@@ -17,34 +17,23 @@
package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.common.utils.Holder;
-import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.cluster.router.RouterResult;
-import org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode;
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
import org.apache.dubbo.rpc.cluster.router.state.BitList;
import org.apache.dubbo.rpc.cluster.router.state.StateRouter;
import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory;
-import org.apache.dubbo.rpc.cluster.router.state.TailStateRouter;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
-import static
org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_STOP;
-import static
org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_NO_VALID_PROVIDER;
+import static
org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_INTERRUPTED;
+import static
org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ROUTER_WAIT_LONG;
import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
/**
@@ -53,34 +42,18 @@ import static
org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
public class RouterChain<T> {
private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(RouterChain.class);
- /**
- * full list of addresses from registry, classified by method name.
- */
- private volatile BitList<Invoker<T>> invokers = BitList.emptyList();
-
- /**
- * containing all routers, reconstruct every time 'route://' urls change.
- */
- private volatile List<Router> routers = Collections.emptyList();
-
- /**
- * Fixed router instances: ConfigConditionRouter, TagRouter, e.g.,
- * the rule for each instance may change but the instance will never
delete or recreate.
- */
- private volatile List<Router> builtinRouters = Collections.emptyList();
-
- private volatile StateRouter<T> headStateRouter;
-
- private volatile List<StateRouter<T>> stateRouters;
-
- /**
- * Should continue route if current router's result is empty
- */
- private final boolean shouldFailFast;
-
- private final RouterSnapshotSwitcher routerSnapshotSwitcher;
+ private final SingleRouterChain<T> mainChain;
+ private final SingleRouterChain<T> backupChain;
+ private volatile SingleRouterChain<T> currentChain;
+ @SuppressWarnings({"rawtypes", "unchecked"})
public static <T> RouterChain<T> buildChain(Class<T> interfaceClass, URL
url) {
+ SingleRouterChain<T> chain1 = buildSingleChain(interfaceClass, url);
+ SingleRouterChain<T> chain2 = buildSingleChain(interfaceClass, url);
+ return new RouterChain<>(new SingleRouterChain[]{chain1, chain2});
+ }
+
+ public static <T> SingleRouterChain<T> buildSingleChain(Class<T>
interfaceClass, URL url) {
ModuleModel moduleModel = url.getOrDefaultModuleModel();
List<RouterFactory> extensionFactories =
moduleModel.getExtensionLoader(RouterFactory.class)
@@ -103,264 +76,95 @@ public class RouterChain<T> {
RouterSnapshotSwitcher routerSnapshotSwitcher =
ScopeModelUtil.getFrameworkModel(moduleModel).getBeanFactory().getBean(RouterSnapshotSwitcher.class);
- return new RouterChain<>(routers, stateRouters, shouldFailFast,
routerSnapshotSwitcher);
+ return new SingleRouterChain<>(routers, stateRouters, shouldFailFast,
routerSnapshotSwitcher);
}
- public RouterChain(List<Router> routers, List<StateRouter<T>>
stateRouters, boolean shouldFailFast, RouterSnapshotSwitcher
routerSnapshotSwitcher) {
- initWithRouters(routers);
-
- initWithStateRouters(stateRouters);
-
- this.shouldFailFast = shouldFailFast;
- this.routerSnapshotSwitcher = routerSnapshotSwitcher;
- }
-
- private void initWithStateRouters(List<StateRouter<T>> stateRouters) {
- StateRouter<T> stateRouter = TailStateRouter.getInstance();
- for (int i = stateRouters.size() - 1; i >= 0; i--) {
- StateRouter<T> nextStateRouter = stateRouters.get(i);
- nextStateRouter.setNextRouter(stateRouter);
- stateRouter = nextStateRouter;
+ public RouterChain(SingleRouterChain<T>[] chains) {
+ if (chains.length != 2) {
+ throw new IllegalArgumentException("chains' size should be 2.");
}
- this.headStateRouter = stateRouter;
- this.stateRouters = Collections.unmodifiableList(stateRouters);
+ this.mainChain = chains[0];
+ this.backupChain = chains[1];
+ this.currentChain = this.mainChain;
}
- /**
- * the resident routers must being initialized before address notification.
- * only for ut
- */
- public void initWithRouters(List<Router> builtinRouters) {
- this.builtinRouters = builtinRouters;
- this.routers = new LinkedList<>(builtinRouters);
+ public List<Invoker<T>> route(URL url, BitList<Invoker<T>>
availableInvokers, Invocation invocation) {
+ return currentChain.route(url, availableInvokers, invocation);
}
/**
- * If we use route:// protocol in version before 2.7.0, each URL will
generate a Router instance, so we should
- * keep the routers up to date, that is, each time router URLs changes, we
should update the routers list, only
- * keep the builtinRouters which are available all the time and the latest
notified routers which are generated
- * from URLs.
- *
- * @param routers routers from 'router://' rules in 2.6.x or before.
+ * Notify router chain of the initial addresses from registry at the first
time.
+ * Notify whenever addresses in registry change.
*/
- public void addRouters(List<Router> routers) {
- List<Router> newRouters = new LinkedList<>();
- newRouters.addAll(builtinRouters);
- newRouters.addAll(routers);
- CollectionUtils.sort(newRouters);
- this.routers = newRouters;
- }
-
- public List<Router> getRouters() {
- return routers;
- }
-
- public StateRouter<T> getHeadStateRouter() {
- return headStateRouter;
- }
-
- public List<Invoker<T>> route(URL url, BitList<Invoker<T>>
availableInvokers, Invocation invocation) {
- if (RpcContext.getServiceContext().isNeedPrintRouterSnapshot()) {
- return routeAndPrint(url, availableInvokers, invocation);
- } else {
- return simpleRoute(url, availableInvokers, invocation);
- }
- }
+ public synchronized void setInvokers(BitList<Invoker<T>> invokers) {
+ // 1. switch
+ currentChain = backupChain;
- public List<Invoker<T>> routeAndPrint(URL url, BitList<Invoker<T>>
availableInvokers, Invocation invocation) {
- RouterSnapshotNode<T> snapshot = buildRouterSnapshot(url,
availableInvokers, invocation);
- logRouterSnapshot(url, invocation, snapshot);
- return snapshot.getChainOutputInvokers();
- }
-
- public List<Invoker<T>> simpleRoute(URL url, BitList<Invoker<T>>
availableInvokers, Invocation invocation) {
- BitList<Invoker<T>> resultInvokers = availableInvokers.clone();
+ // 2. wait
+ waitChain(mainChain);
- // 1. route state router
- resultInvokers = headStateRouter.route(resultInvokers, url,
invocation, false, null);
- if (resultInvokers.isEmpty() && (shouldFailFast || routers.isEmpty()))
{
- printRouterSnapshot(url, availableInvokers, invocation);
- return BitList.emptyList();
- }
+ // 3. notify
+ mainChain.setInvokers(invokers);
- if (routers.isEmpty()) {
- return resultInvokers;
- }
- List<Invoker<T>> commonRouterResult =
resultInvokers.cloneToArrayList();
- // 2. route common router
- for (Router router : routers) {
- // Copy resultInvokers to a arrayList. BitList not support
- RouterResult<Invoker<T>> routeResult =
router.route(commonRouterResult, url, invocation, false);
- commonRouterResult = routeResult.getResult();
- if (CollectionUtils.isEmpty(commonRouterResult) && shouldFailFast)
{
- printRouterSnapshot(url, availableInvokers, invocation);
- return BitList.emptyList();
- }
-
- // stop continue routing
- if (!routeResult.isNeedContinueRoute()) {
- return commonRouterResult;
- }
- }
+ // 4. switch back
+ currentChain = mainChain;
- if (commonRouterResult.isEmpty()) {
- printRouterSnapshot(url, availableInvokers, invocation);
- return BitList.emptyList();
- }
+ // 5. wait
+ waitChain(backupChain);
- return commonRouterResult;
+ // 6. notify
+ backupChain.setInvokers(invokers);
}
- /**
- * store each router's input and output, log out if empty
- */
- private void printRouterSnapshot(URL url, BitList<Invoker<T>>
availableInvokers, Invocation invocation) {
- if (logger.isWarnEnabled()) {
- logRouterSnapshot(url, invocation, buildRouterSnapshot(url,
availableInvokers, invocation));
+ private void waitChain(SingleRouterChain<T> oldChain) {
+ try {
+ Thread.sleep(1);
+ int waitTime = 0;
+ while (oldChain.getCurrentConcurrency() != 0) {
+ if (waitTime++ == 1000) {
+ logger.warn(REGISTRY_ROUTER_WAIT_LONG, "Wait router to
long", "", "Wait router invoke end exceed 1000ms, router may stuck in.");
+ }
+ // long time wait
+ Thread.sleep(1);
+ }
+ } catch (Throwable t) {
+ logger.error(INTERNAL_INTERRUPTED, "Wait router to interrupted",
"", "Wait router to interrupted.");
}
}
- /**
- * Build each router's result
- */
- public RouterSnapshotNode<T> buildRouterSnapshot(URL url,
BitList<Invoker<T>> availableInvokers, Invocation invocation) {
- BitList<Invoker<T>> resultInvokers = availableInvokers.clone();
- RouterSnapshotNode<T> parentNode = new RouterSnapshotNode<T>("Parent",
resultInvokers.clone());
- parentNode.setNodeOutputInvokers(resultInvokers.clone());
-
- // 1. route state router
- Holder<RouterSnapshotNode<T>> nodeHolder = new Holder<>();
- nodeHolder.set(parentNode);
-
- resultInvokers = headStateRouter.route(resultInvokers, url,
invocation, true, nodeHolder);
-
- // result is empty, log out
- if (routers.isEmpty() || (resultInvokers.isEmpty() && shouldFailFast))
{
- parentNode.setChainOutputInvokers(resultInvokers.clone());
- return parentNode;
- }
-
- RouterSnapshotNode<T> commonRouterNode = new
RouterSnapshotNode<T>("CommonRouter", resultInvokers.clone());
- parentNode.appendNode(commonRouterNode);
- List<Invoker<T>> commonRouterResult = resultInvokers;
+ public synchronized void destroy() {
+ // 1. destroy another
+ backupChain.destroy();
- // 2. route common router
- for (Router router : routers) {
- // Copy resultInvokers to a arrayList. BitList not support
- List<Invoker<T>> inputInvokers = new
ArrayList<>(commonRouterResult);
+ // 2. switch
+ currentChain = backupChain;
- RouterSnapshotNode<T> currentNode = new
RouterSnapshotNode<T>(router.getClass().getSimpleName(), inputInvokers);
+ // 3. wait
+ waitChain(mainChain);
- // append to router node chain
- commonRouterNode.appendNode(currentNode);
- commonRouterNode = currentNode;
-
- RouterResult<Invoker<T>> routeStateResult =
router.route(inputInvokers, url, invocation, true);
- List<Invoker<T>> routeResult = routeStateResult.getResult();
- String routerMessage = routeStateResult.getMessage();
-
- currentNode.setNodeOutputInvokers(routeResult);
- currentNode.setRouterMessage(routerMessage);
-
- commonRouterResult = routeResult;
-
- // result is empty, log out
- if (CollectionUtils.isEmpty(routeResult) && shouldFailFast) {
- break;
- }
+ // 4. destroy
+ mainChain.destroy();
+ }
- if (!routeStateResult.isNeedContinueRoute()) {
- break;
- }
- }
-
commonRouterNode.setChainOutputInvokers(commonRouterNode.getNodeOutputInvokers());
-
- // 3. set router chain output reverse
- RouterSnapshotNode<T> currentNode = commonRouterNode;
- while (currentNode != null){
- RouterSnapshotNode<T> parent = currentNode.getParentNode();
- if (parent != null) {
- // common router only has one child invoke
-
parent.setChainOutputInvokers(currentNode.getChainOutputInvokers());
- }
- currentNode = parent;
- }
- return parentNode;
+ public void addRouters(List<Router> routers) {
+ mainChain.addRouters(routers);
+ backupChain.addRouters(routers);
}
- private void logRouterSnapshot(URL url, Invocation invocation,
RouterSnapshotNode<T> snapshotNode) {
- if (snapshotNode.getChainOutputInvokers() == null ||
- snapshotNode.getChainOutputInvokers().isEmpty()) {
- if (logger.isWarnEnabled()) {
- String message = "No provider available after route for the
service " + url.getServiceKey()
- + " from registry " + url.getAddress()
- + " on the consumer " + NetUtils.getLocalHost()
- + " using the dubbo version " + Version.getVersion() + ".
Router snapshot is below: \n" + snapshotNode.toString();
- if (routerSnapshotSwitcher.isEnable()) {
- routerSnapshotSwitcher.setSnapshot(message);
- }
- logger.warn(CLUSTER_NO_VALID_PROVIDER,"No provider available
after route for the service","",message);
- }
- } else {
- if (logger.isInfoEnabled()) {
- String message = "Router snapshot service " +
url.getServiceKey()
- + " from registry " + url.getAddress()
- + " on the consumer " + NetUtils.getLocalHost()
- + " using the dubbo version " + Version.getVersion() + "
is below: \n" + snapshotNode.toString();
- if (routerSnapshotSwitcher.isEnable()) {
- routerSnapshotSwitcher.setSnapshot(message);
- }
- logger.info(message);
- }
- }
+ public SingleRouterChain<T> getCurrentChain() {
+ return currentChain;
}
- /**
- * Notify router chain of the initial addresses from registry at the first
time.
- * Notify whenever addresses in registry change.
- */
- public void setInvokers(BitList<Invoker<T>> invokers) {
- this.invokers = (invokers == null ? BitList.emptyList() : invokers);
- routers.forEach(router -> router.notify(this.invokers));
- stateRouters.forEach(router -> router.notify(this.invokers));
+ public List<Router> getRouters() {
+ return currentChain.getRouters();
}
- /**
- * for uts only
- */
- @Deprecated
- public void setHeadStateRouter(StateRouter<T> headStateRouter) {
- this.headStateRouter = headStateRouter;
+ public StateRouter<T> getHeadStateRouter() {
+ return currentChain.getHeadStateRouter();
}
- /**
- * for uts only
- */
@Deprecated
public List<StateRouter<T>> getStateRouters() {
- return stateRouters;
- }
-
- public void destroy() {
- invokers = BitList.emptyList();
- for (Router router : routers) {
- try {
- router.stop();
- } catch (Exception e) {
- logger.error(CLUSTER_FAILED_STOP,"route stop failed","","Error
trying to stop router " + router.getClass(),e);
- }
- }
- routers = Collections.emptyList();
- builtinRouters = Collections.emptyList();
-
- for (StateRouter<T> router : stateRouters) {
- try {
- router.stop();
- } catch (Exception e) {
- logger.error(CLUSTER_FAILED_STOP,"StateRouter stop
failed","","Error trying to stop StateRouter " + router.getClass(),e);
- }
- }
- stateRouters = Collections.emptyList();
- headStateRouter = TailStateRouter.getInstance();
+ return currentChain.getStateRouters();
}
}
diff --git
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/SingleRouterChain.java
similarity index 86%
copy from
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
copy to
dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/SingleRouterChain.java
index 64246b9ea5..73e74459a5 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
+++
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/SingleRouterChain.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
-import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
@@ -32,26 +31,22 @@ import
org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode;
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
import org.apache.dubbo.rpc.cluster.router.state.BitList;
import org.apache.dubbo.rpc.cluster.router.state.StateRouter;
-import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory;
import org.apache.dubbo.rpc.cluster.router.state.TailStateRouter;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.stream.Collectors;
+import java.util.concurrent.atomic.AtomicInteger;
import static
org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_STOP;
import static
org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_NO_VALID_PROVIDER;
-import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
/**
* Router chain
*/
-public class RouterChain<T> {
- private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(RouterChain.class);
+public class SingleRouterChain<T> {
+ private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(SingleRouterChain.class);
/**
* full list of addresses from registry, classified by method name.
@@ -80,33 +75,9 @@ public class RouterChain<T> {
private final RouterSnapshotSwitcher routerSnapshotSwitcher;
- public static <T> RouterChain<T> buildChain(Class<T> interfaceClass, URL
url) {
- ModuleModel moduleModel = url.getOrDefaultModuleModel();
+ private final AtomicInteger currentConcurrency = new AtomicInteger(0);
- List<RouterFactory> extensionFactories =
moduleModel.getExtensionLoader(RouterFactory.class)
- .getActivateExtension(url, ROUTER_KEY);
-
- List<Router> routers = extensionFactories.stream()
- .map(factory -> factory.getRouter(url))
- .sorted(Router::compareTo)
- .collect(Collectors.toList());
-
- List<StateRouter<T>> stateRouters = moduleModel
- .getExtensionLoader(StateRouterFactory.class)
- .getActivateExtension(url, ROUTER_KEY)
- .stream()
- .map(factory -> factory.getRouter(interfaceClass, url))
- .collect(Collectors.toList());
-
-
- boolean shouldFailFast =
Boolean.parseBoolean(ConfigurationUtils.getProperty(moduleModel,
Constants.SHOULD_FAIL_FAST_KEY, "true"));
-
- RouterSnapshotSwitcher routerSnapshotSwitcher =
ScopeModelUtil.getFrameworkModel(moduleModel).getBeanFactory().getBean(RouterSnapshotSwitcher.class);
-
- return new RouterChain<>(routers, stateRouters, shouldFailFast,
routerSnapshotSwitcher);
- }
-
- public RouterChain(List<Router> routers, List<StateRouter<T>>
stateRouters, boolean shouldFailFast, RouterSnapshotSwitcher
routerSnapshotSwitcher) {
+ public SingleRouterChain(List<Router> routers, List<StateRouter<T>>
stateRouters, boolean shouldFailFast, RouterSnapshotSwitcher
routerSnapshotSwitcher) {
initWithRouters(routers);
initWithStateRouters(stateRouters);
@@ -160,10 +131,15 @@ public class RouterChain<T> {
}
public List<Invoker<T>> route(URL url, BitList<Invoker<T>>
availableInvokers, Invocation invocation) {
- if (RpcContext.getServiceContext().isNeedPrintRouterSnapshot()) {
- return routeAndPrint(url, availableInvokers, invocation);
- } else {
- return simpleRoute(url, availableInvokers, invocation);
+ currentConcurrency.incrementAndGet();
+ try {
+ if (RpcContext.getServiceContext().isNeedPrintRouterSnapshot()) {
+ return routeAndPrint(url, availableInvokers, invocation);
+ } else {
+ return simpleRoute(url, availableInvokers, invocation);
+ }
+ } finally {
+ currentConcurrency.decrementAndGet();
}
}
@@ -341,6 +317,10 @@ public class RouterChain<T> {
return stateRouters;
}
+ public int getCurrentConcurrency() {
+ return currentConcurrency.get();
+ }
+
public void destroy() {
invokers = BitList.emptyList();
for (Router router : routers) {
diff --git
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java
index a81a1eaacb..2da97cb2e1 100644
---
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java
+++
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java
@@ -113,15 +113,16 @@ public abstract class AbstractStateRouter<T> implements
StateRouter<T> {
}
BitList<Invoker<T>> routeResult;
+ routeResult = doRoute(invokers, url, invocation, needToPrintMessage,
nodeHolder, messageHolder);
+ if (routeResult != invokers) {
+ routeResult = invokers.and(routeResult);
+ }
// check if router support call continue route by itself
if (!supportContinueRoute()) {
- routeResult = doRoute(invokers, url, invocation,
needToPrintMessage, nodeHolder, messageHolder);
// use current node's result as next node's parameter
if (!shouldFailFast || !routeResult.isEmpty()) {
routeResult = continueRoute(routeResult, url, invocation,
needToPrintMessage, nodeHolder);
}
- } else {
- routeResult = doRoute(invokers, url, invocation,
needToPrintMessage, nodeHolder, messageHolder);
}
// post-build current node
@@ -190,7 +191,7 @@ public abstract class AbstractStateRouter<T> implements
StateRouter<T> {
@Override
public final String buildSnapshot() {
return doBuildSnapshot() +
- " ↓ \n" +
+ " v \n" +
nextRouter.buildSnapshot();
}
diff --git
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java
index ce0027e290..9694bf9f51 100644
---
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java
+++
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java
@@ -118,10 +118,13 @@ public class BitList<E> extends AbstractList<E> {
* TailList in source bitList will be totally saved even if it is not
appeared in the target bitList.
*
* @param target target bitList
- * @return a new bitList only contains those elements contain in both two
list and source bitList's tailList
+ * @return this bitList only contains those elements contain in both two
list and source bitList's tailList
*/
public BitList<E> and(BitList<E> target) {
rootSet.and(target.rootSet);
+ if (target.getTailList() != null) {
+ target.getTailList().forEach(this::addToTailList);
+ }
return this;
}
diff --git
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java
index 288b7bca31..1be30ff983 100644
---
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java
+++
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java
@@ -59,7 +59,7 @@ public class StaticDirectoryTest {
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"),
new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" +
NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation(), false,
new Holder<>());
StaticDirectory<String> staticDirectory = new
StaticDirectory<>(filteredInvokers);
boolean isAvailable = staticDirectory.isAvailable();
Assertions.assertTrue(!isAvailable);
diff --git
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java
index 5698dc6785..1c6c799cad 100644
---
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java
+++
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java
@@ -124,12 +124,12 @@ public class ConditionStateRouterTest {
- List<Invoker<String>> filteredInvokers1 = router1.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
- List<Invoker<String>> filteredInvokers2 = router2.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
- List<Invoker<String>> filteredInvokers3 = router3.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
- List<Invoker<String>> filteredInvokers4 = router4.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
- List<Invoker<String>> filteredInvokers5 = router5.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
- List<Invoker<String>> filteredInvokers6 = router6.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers1 =
router1.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers2 =
router2.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers3 =
router3.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers4 =
router4.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers5 =
router5.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers6 =
router6.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(1, filteredInvokers1.size());
Assertions.assertEquals(0, filteredInvokers2.size());
Assertions.assertEquals(0, filteredInvokers3.size());
@@ -177,14 +177,14 @@ public class ConditionStateRouterTest {
StateRouter router4 = new
ConditionStateRouterFactory().getRouter(String.class, getRouteUrl(
"host = " + LOCAL_HOST + " & methods = getFoo => " + " host =
10.20.3.3").addParameter(
FORCE_KEY, String.valueOf(true)));
- List<Invoker<String>> filteredInvokers1 = router4.route(invokers,
+ List<Invoker<String>> filteredInvokers1 =
router4.route(invokers.clone(),
URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), invocation, false, new Holder<>());
Assertions.assertEquals(1, filteredInvokers1.size());
StateRouter router5 = new
ConditionStateRouterFactory().getRouter(String.class, getRouteUrl(
"host = " + LOCAL_HOST + " & methods = unvalidmethod => " + "
host = 10.20.3.3")
.addParameter(FORCE_KEY, String.valueOf(true)));
- List<Invoker<String>> filteredInvokers2 = router5.route(invokers,
+ List<Invoker<String>> filteredInvokers2 =
router5.route(invokers.clone(),
URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), invocation, false, new Holder<>());
Assertions.assertEquals(3, filteredInvokers2.size());
// Request a non-exists method
@@ -199,7 +199,7 @@ public class ConditionStateRouterTest {
originInvokers.add(new MockInvoker<String>());
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(0, filteredInvokers.size());
}
@@ -212,7 +212,7 @@ public class ConditionStateRouterTest {
originInvokers.add(new MockInvoker<String>());
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(0, filteredInvokers.size());
}
@@ -225,7 +225,7 @@ public class ConditionStateRouterTest {
originInvokers.add(new MockInvoker<String>(URL.valueOf("dubbo://" +
LOCAL_HOST + ":20880/com.foo.BarService")));
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(invokers, filteredInvokers);
}
@@ -241,7 +241,7 @@ public class ConditionStateRouterTest {
originInvokers.add(invoker3);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(2, filteredInvokers.size());
Assertions.assertEquals(invoker2, filteredInvokers.get(0));
Assertions.assertEquals(invoker3, filteredInvokers.get(1));
@@ -259,7 +259,7 @@ public class ConditionStateRouterTest {
originInvokers.add(invoker3);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(2, filteredInvokers.size());
Assertions.assertEquals(invoker2, filteredInvokers.get(0));
Assertions.assertEquals(invoker3, filteredInvokers.get(1));
@@ -277,7 +277,7 @@ public class ConditionStateRouterTest {
originInvokers.add(invoker3);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(2, filteredInvokers.size());
Assertions.assertEquals(invoker2, filteredInvokers.get(0));
Assertions.assertEquals(invoker3, filteredInvokers.get(1));
@@ -295,7 +295,7 @@ public class ConditionStateRouterTest {
originInvokers.add(invoker3);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(2, filteredInvokers.size());
Assertions.assertEquals(invoker2, filteredInvokers.get(0));
Assertions.assertEquals(invoker3, filteredInvokers.get(1));
@@ -313,7 +313,7 @@ public class ConditionStateRouterTest {
originInvokers.add(invoker3);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(invokers, filteredInvokers);
}
@@ -329,7 +329,7 @@ public class ConditionStateRouterTest {
originInvokers.add(invoker3);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), new
RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST +
"/com.foo.BarService"), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(0, filteredInvokers.size());
}
@@ -348,25 +348,25 @@ public class ConditionStateRouterTest {
RpcInvocation invocation = new RpcInvocation();
String p = "a";
invocation.setArguments(new Object[]{null});
- List<Invoker<String>> fileredInvokers = router.route(invokers,
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation,
false, new Holder<>());
+ List<Invoker<String>> fileredInvokers = router.route(invokers.clone(),
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation,
false, new Holder<>());
Assertions.assertEquals(3, fileredInvokers.size());
invocation.setArguments(new Object[]{p});
- fileredInvokers = router.route(invokers, URL.valueOf("consumer://" +
LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>());
+ fileredInvokers = router.route(invokers.clone(),
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation,
false, new Holder<>());
Assertions.assertEquals(0, fileredInvokers.size());
router = new ConditionStateRouterFactory().getRouter(String.class,
getRouteUrl("arguments = b " + " => " + " host =
1.2.3.4").addParameter(FORCE_KEY, String.valueOf(true)));
- fileredInvokers = router.route(invokers, URL.valueOf("consumer://" +
LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>());
+ fileredInvokers = router.route(invokers.clone(),
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation,
false, new Holder<>());
Assertions.assertEquals(3, fileredInvokers.size());
router = new ConditionStateRouterFactory().getRouter(String.class,
getRouteUrl("arguments[10].inner = a " + " => " + " host =
1.2.3.4").addParameter(FORCE_KEY, String.valueOf(true)));
- fileredInvokers = router.route(invokers, URL.valueOf("consumer://" +
LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>());
+ fileredInvokers = router.route(invokers.clone(),
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation,
false, new Holder<>());
Assertions.assertEquals(3, fileredInvokers.size());
int integer = 1;
invocation.setArguments(new Object[]{integer});
router = new ConditionStateRouterFactory().getRouter(String.class,
getRouteUrl("arguments[0].inner = 1 " + " => " + " host =
1.2.3.4").addParameter(FORCE_KEY, String.valueOf(true)));
- fileredInvokers = router.route(invokers, URL.valueOf("consumer://" +
LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>());
+ fileredInvokers = router.route(invokers.clone(),
URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation,
false, new Holder<>());
Assertions.assertEquals(0, fileredInvokers.size());
}
}
diff --git
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java
index 6cfc1e3a25..7c0d2d0781 100644
---
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java
+++
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java
@@ -172,7 +172,7 @@ public class FileRouterEngineTest {
URL dicInitUrl =
URL.valueOf("consumer://localhost:20880/org.apache.dubbo.rpc.cluster.router.file.FileRouterEngineTest?application=FileRouterEngineTest");
dic = new StaticDirectory<>(dicInitUrl, invokers);
dic.buildRouterChain();
-
dic.getRouterChain().setHeadStateRouter(routerFactory.getRouter(FileRouterEngineTest.class,
url));
+
dic.getRouterChain().getCurrentChain().setHeadStateRouter(routerFactory.getRouter(FileRouterEngineTest.class,
url));
}
static class MockClusterInvoker<T> extends AbstractClusterInvoker<T> {
diff --git
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/ScriptStateRouterTest.java
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/ScriptStateRouterTest.java
index 8be79f9db7..13a9a03880 100644
---
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/ScriptStateRouterTest.java
+++
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/ScriptStateRouterTest.java
@@ -63,7 +63,7 @@ public class ScriptStateRouterTest {
originInvokers.add(new MockInvoker<String>());
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
invokers.get(0).getUrl(), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), invokers.get(0).getUrl(), new RpcInvocation(),
false, new Holder<>());
Assertions.assertEquals(invokers, filteredInvokers);
}
@@ -88,7 +88,7 @@ public class ScriptStateRouterTest {
originInvokers.add(invoker3);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
- List<Invoker<String>> filteredInvokers = router.route(invokers,
invokers.get(0).getUrl(), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), invokers.get(0).getUrl(), new RpcInvocation(),
false, new Holder<>());
Assertions.assertEquals(2, filteredInvokers.size());
Assertions.assertEquals(invoker2, filteredInvokers.get(0));
Assertions.assertEquals(invoker3, filteredInvokers.get(1));
@@ -119,7 +119,7 @@ public class ScriptStateRouterTest {
"route(invokers, invocation, context) ";
StateRouter router = new
ScriptStateRouterFactory().getRouter(String.class, getRouteUrl(script));
- List<Invoker<String>> routeResult = router.route(invokers,
invokers.get(0).getUrl(), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> routeResult = router.route(invokers.clone(),
invokers.get(0).getUrl(), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(1, routeResult.size());
Assertions.assertEquals(invoker2, routeResult.get(0));
}
@@ -137,7 +137,7 @@ public class ScriptStateRouterTest {
String script = "/";
StateRouter router = new
ScriptStateRouterFactory().getRouter(String.class, getRouteUrl(script));
- List<Invoker<String>> routeResult = router.route(invokers,
invokers.get(0).getUrl(), new RpcInvocation(), false, new Holder<>());
+ List<Invoker<String>> routeResult = router.route(invokers.clone(),
invokers.get(0).getUrl(), new RpcInvocation(), false, new Holder<>());
Assertions.assertEquals(3, routeResult.size());
}
}
diff --git
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java
index 18c14319a4..0604240166 100644
---
a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java
+++
b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java
@@ -32,6 +32,7 @@ import
org.apache.dubbo.rpc.cluster.router.tag.model.TagRouterRule;
import org.apache.dubbo.rpc.cluster.router.tag.model.TagRuleParser;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ModuleModel;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -88,7 +89,7 @@ public class TagStateRouterTest {
RpcInvocation invocation = new RpcInvocation();
invocation.setAttachment(TAG_KEY, "tag2");
- List<Invoker<String>> filteredInvokers = router.route(invokers,
invokers.get(0).getUrl(), invocation, false, new Holder<>());
+ List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), invokers.get(0).getUrl(), invocation, false, new
Holder<>());
Assertions.assertEquals(1, filteredInvokers.size());
Assertions.assertEquals(invoker1, filteredInvokers.get(0));
}
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
index 5dc83f19dd..78304d3c93 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java
@@ -71,6 +71,8 @@ public interface LoggerCodeConstants {
String REGISTRY_MISSING_METADATA_CONFIG_PORT = "1-18";
+ String REGISTRY_ROUTER_WAIT_LONG = "1-19";
+
// cluster module 2-1 ~ 2-18
String CLUSTER_FAILED_SITE_SELECTION = "2-1";
@@ -166,4 +168,7 @@ public interface LoggerCodeConstants {
String INTERNAL_SERVICE_CONFIG_ERROR = "6-3";
+ String INTERNAL_ERROR = "99-0";
+
+ String INTERNAL_INTERRUPTED = "99-1";
}