Skip to content

Commit

Permalink
[FEATURE]:[给状态机提供一些新操作接口]
Browse files Browse the repository at this point in the history
1. 增加com.alibaba.cola.statemachine.StateMachine#verify方法
用来判断当前状态能否响应某个事件

2. 增加com.alibaba.cola.statemachine.builder.StateMachineBuilder#setFailoverCallback
用来增加在状态流转没有命中当前配置的规则时执行的回调
接口定义 com.alibaba.cola.statemachine.builder.FailoverCallback
默认为NumbFailoverCallbackImpl,与当前行为一样,什么都不做。
另外内置AlertFailoverCallbackImpl,用于抛出异常TransitionFailoverException
  • Loading branch information
Ivan97 committed Sep 15, 2022
1 parent 3ac5b4e commit e072976
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 65 deletions.
1 change: 1 addition & 0 deletions cola-components/cola-component-statemachine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</parent>

<artifactId>cola-component-statemachine</artifactId>
<version>4.4.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>${project.artifactId}</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
*/
public interface StateMachine<S, E, C> extends Visitable{

/**
* Verify if an event {@code E} can be fired from current state {@code S}
* @param sourceStateId
* @param event
* @return
*/
boolean verify(S sourceStateId,E event);

/**
* Send an event {@code E} to the state machine.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.alibaba.cola.statemachine.builder;

import com.alibaba.cola.statemachine.exception.TransitionFailoverException;

/**
* Default failover callback, do nothing.
*
* @author 龙也
* @date 2022/9/15 12:02 PM
*/
public class AlertFailoverCallbackImpl<S, E, C> implements FailoverCallback<S, E, C> {

@Override
public void onFailover(S sourceState, E event, C context) {
throw new TransitionFailoverException(
"Cannot fire event [" + event + "] on current state [" + sourceState + "] with context [" + context + "]");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.alibaba.cola.statemachine.builder;

/**
* @author 龙也
* @date 2022/9/15 12:02 PM
*/
@FunctionalInterface
public interface FailoverCallback<S, E, C> {

/**
* Callback function to execute on failover
*
* @param sourceState
* @param event
* @param context
*/
void onFailover(S sourceState, E event, C context);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.alibaba.cola.statemachine.builder;

/**
* Default failover callback, do nothing.
*
* @author 龙也
* @date 2022/9/15 12:02 PM
*/
public class NumbFailoverCallbackImpl<S, E, C> implements FailoverCallback<S, E, C> {

@Override
public void onFailover(S sourceState, E event, C context) {
//do nothing
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,32 @@
public interface StateMachineBuilder<S, E, C> {
/**
* Builder for one transition
*
* @return External transition builder
*/
ExternalTransitionBuilder<S, E, C> externalTransition();

/**
* Builder for multiple transitions
*
* @return External transition builder
*/
ExternalTransitionsBuilder<S, E, C> externalTransitions();

/**
* Start to build internal transition
*
* @return Internal transition builder
*/
InternalTransitionBuilder<S, E, C> internalTransition();

StateMachine<S,E,C> build(String machineId);
/**
* set up failover callback, default do nothing {@code NumbFailoverCallbackImpl}
*
* @param callback
*/
void setFailoverCallback(FailoverCallback<S, E, C> callback);

StateMachine<S, E, C> build(String machineId);

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.alibaba.cola.statemachine.builder;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.cola.statemachine.State;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.StateMachineFactory;
import com.alibaba.cola.statemachine.impl.StateMachineImpl;
import com.alibaba.cola.statemachine.impl.TransitionType;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* StateMachineBuilderImpl
*
Expand All @@ -20,8 +20,9 @@ public class StateMachineBuilderImpl<S, E, C> implements StateMachineBuilder<S,
/**
* StateMap is the same with stateMachine, as the core of state machine is holding reference to states.
*/
private final Map<S, State< S, E, C>> stateMap = new ConcurrentHashMap<>();
private final Map<S, State<S, E, C>> stateMap = new ConcurrentHashMap<>();
private final StateMachineImpl<S, E, C> stateMachine = new StateMachineImpl<>(stateMap);
private FailoverCallback<S, E, C> failoverCallback = new NumbFailoverCallbackImpl<>();

@Override
public ExternalTransitionBuilder<S, E, C> externalTransition() {
Expand All @@ -38,10 +39,16 @@ public InternalTransitionBuilder<S, E, C> internalTransition() {
return new TransitionBuilderImpl<>(stateMap, TransitionType.INTERNAL);
}

@Override
public void setFailoverCallback(FailoverCallback<S, E, C> callback) {
this.failoverCallback = callback;
}

@Override
public StateMachine<S, E, C> build(String machineId) {
stateMachine.setMachineId(machineId);
stateMachine.setReady(true);
stateMachine.setFailoverCallback(failoverCallback);
StateMachineFactory.register(stateMachine);
return stateMachine;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.alibaba.cola.statemachine.exception;

/**
* @author 龙也
* @date 2022/9/15 12:08 PM
*/
public class TransitionFailoverException extends RuntimeException {

public TransitionFailoverException(String errMsg) {
super(errMsg);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.alibaba.cola.statemachine.impl;

import java.util.List;
import java.util.Map;

import com.alibaba.cola.statemachine.State;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.Transition;
import com.alibaba.cola.statemachine.Visitor;

import java.util.List;
import java.util.Map;
import com.alibaba.cola.statemachine.builder.FailoverCallback;

/**
* For performance consideration,
Expand All @@ -26,17 +27,31 @@ public class StateMachineImpl<S, E, C> implements StateMachine<S, E, C> {

private boolean ready;

private FailoverCallback<S, E, C> failoverCallback;

public StateMachineImpl(Map<S, State<S, E, C>> stateMap) {
this.stateMap = stateMap;
}

@Override
public boolean verify(S sourceStateId, E event) {
isReady();

State sourceState = getState(sourceStateId);

List<Transition<S, E, C>> transitions = sourceState.getEventTransitions(event);

return transitions != null && transitions.size() != 0;
}

@Override
public S fireEvent(S sourceStateId, E event, C ctx) {
isReady();
Transition<S, E, C> transition = routeTransition(sourceStateId, event, ctx);

if (transition == null) {
Debugger.debug("There is no Transition for " + event);
failoverCallback.onFailover(sourceStateId, event, ctx);
return sourceStateId;
}

Expand Down Expand Up @@ -115,4 +130,8 @@ public void setMachineId(String machineId) {
public void setReady(boolean ready) {
this.ready = ready;
}

public void setFailoverCallback(FailoverCallback<S, E, C> failoverCallback) {
this.failoverCallback = failoverCallback;
}
}
Loading

0 comments on commit e072976

Please sign in to comment.