mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
refactor(action): support executing any type of Actions with virtual thread in ActionExecutor, ActionScheduler will send actionData to executor directly
This commit is contained in:
@@ -50,104 +50,121 @@ public class ActionExecutor extends AbstractAgentModule.Standalone {
|
|||||||
runnerClient = actionCapability.runnerClient();
|
runnerClient = actionCapability.runnerClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void execute(Action action) {
|
||||||
* 执行行动
|
virtualExecutor.execute(actionExecutionRouter(action));
|
||||||
*
|
}
|
||||||
* @param input ActionExecutor 输入内容
|
|
||||||
*/
|
private Runnable actionExecutionRouter(Action action) {
|
||||||
public void execute(ActionExecutorInput input) {
|
return () -> {
|
||||||
val actions = input.getActions();
|
try {
|
||||||
// 异步执行所有行动
|
switch (action) {
|
||||||
for (ExecutableAction executableAction : actions) {
|
case ExecutableAction executableAction -> handleExecutableAction(executableAction);
|
||||||
platformExecutor.execute(() -> {
|
case StateAction stateAction -> handleStateAction(stateAction);
|
||||||
val source = executableAction.getSource();
|
default -> handleUnknownAction(action);
|
||||||
if (executableAction.getStatus() != Action.Status.PREPARE) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
val actionChain = executableAction.getActionChain();
|
} catch (Exception e) {
|
||||||
if (actionChain.isEmpty()) {
|
log.warn("Action execute failure, uuid: {}, description: {}, failure reason: {}", action.getUuid(), action.getDescription(), e.getLocalizedMessage());
|
||||||
executableAction.setStatus(Action.Status.FAILED);
|
action.setStatus(Action.Status.FAILED);
|
||||||
executableAction.setResult("行动链为空");
|
}
|
||||||
return;
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleUnknownAction(Action action) {
|
||||||
|
log.warn("unknown Action type: {}", action.getClass().getSimpleName());
|
||||||
|
action.setStatus(Action.Status.FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleStateAction(StateAction stateAction) {
|
||||||
|
stateAction.getTrigger().onTrigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleExecutableAction(ExecutableAction executableAction) {
|
||||||
|
val source = executableAction.getSource();
|
||||||
|
if (executableAction.getStatus() != Action.Status.PREPARE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val actionChain = executableAction.getActionChain();
|
||||||
|
if (actionChain.isEmpty()) {
|
||||||
|
executableAction.setStatus(Action.Status.FAILED);
|
||||||
|
executableAction.setResult("行动链为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 注册执行中行动
|
||||||
|
val phaser = new Phaser();
|
||||||
|
val phaserRecord = actionCapability.putPhaserRecord(phaser, executableAction);
|
||||||
|
executableAction.setStatus(Action.Status.EXECUTING);
|
||||||
|
// 开始执行
|
||||||
|
val stageCursor = new Object() {
|
||||||
|
int stageCount;
|
||||||
|
boolean executingStageUpdated;
|
||||||
|
boolean stageCountUpdated;
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
stageCount = 0;
|
||||||
|
executingStageUpdated = false;
|
||||||
|
stageCountUpdated = false;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void requestAdvance() {
|
||||||
|
if (!stageCountUpdated) {
|
||||||
|
stageCount++;
|
||||||
|
stageCountUpdated = true;
|
||||||
}
|
}
|
||||||
// 注册执行中行动
|
if (stageCount < actionChain.size() && !executingStageUpdated) {
|
||||||
val phaser = new Phaser();
|
update();
|
||||||
val phaserRecord = actionCapability.putPhaserRecord(phaser, executableAction);
|
executingStageUpdated = true;
|
||||||
executableAction.setStatus(Action.Status.EXECUTING);
|
|
||||||
// 开始执行
|
|
||||||
val stageCursor = new Object() {
|
|
||||||
int stageCount;
|
|
||||||
boolean executingStageUpdated;
|
|
||||||
boolean stageCountUpdated;
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
stageCount = 0;
|
|
||||||
executingStageUpdated = false;
|
|
||||||
stageCountUpdated = false;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void requestAdvance() {
|
|
||||||
if (!stageCountUpdated) {
|
|
||||||
stageCount++;
|
|
||||||
stageCountUpdated = true;
|
|
||||||
}
|
|
||||||
if (stageCount < actionChain.size() && !executingStageUpdated) {
|
|
||||||
update();
|
|
||||||
executingStageUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean next() {
|
|
||||||
executingStageUpdated = false;
|
|
||||||
stageCountUpdated = false;
|
|
||||||
return stageCount < actionChain.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void update() {
|
|
||||||
val orderList = new ArrayList<>(actionChain.keySet());
|
|
||||||
orderList.sort(Integer::compareTo);
|
|
||||||
executableAction.setExecutingStage(orderList.get(stageCount));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
stageCursor.init();
|
|
||||||
do {
|
|
||||||
val metaActions = actionChain.get(executableAction.getExecutingStage());
|
|
||||||
val listeningRecord = executeAndListening(metaActions, phaserRecord, source);
|
|
||||||
phaser.awaitAdvance(listeningRecord.phase());
|
|
||||||
// synchronized 同步防止 accepting 循环间、phase guard 判定后发生 stage 推进
|
|
||||||
// 导致新行动的 phaser 投放阶段错乱无法阻塞的场景
|
|
||||||
// 该 synchronized 将阶段推进与 accepting 监听 loop 捆绑为互斥的原子事件,避免了细粒度的 phaser 阶段竞态问题
|
|
||||||
synchronized (listeningRecord.accepting()) {
|
|
||||||
listeningRecord.accepting().set(false);
|
|
||||||
// 立即尝试推进,本次推进中,如果前方仍有未执行 stage,将执行一次阶段推进
|
|
||||||
stageCursor.requestAdvance();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// 针对行动链进行修正,修正需要传入执行历史、行动目标等内容
|
|
||||||
// 如果后续运行 corrector 触发频率较高,可考虑增加重试机制
|
|
||||||
val correctorInput = assemblyHelper.buildCorrectorInput(executableAction, source);
|
|
||||||
val correctorResult = actionCorrector.execute(correctorInput);
|
|
||||||
actionCapability.handleInterventions(correctorResult.getMetaInterventionList(), executableAction);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
// 第二次尝试进行阶段推进,本次负责补充上一次在不存在 stage时,但 corrector 执行期间发生了 actionChain 的插入事件
|
|
||||||
// 如果第一次已经推进完毕,本次将会跳过
|
|
||||||
stageCursor.requestAdvance();
|
|
||||||
} while (stageCursor.next());
|
|
||||||
// 结束
|
|
||||||
actionCapability.removePhaserRecord(phaser);
|
|
||||||
if (executableAction.getStatus() != Action.Status.FAILED) {
|
|
||||||
// 如果是 ScheduledActionData, 则重置 ActionData 内容,记录执行历史与最终结果
|
|
||||||
if (executableAction instanceof SchedulableExecutableAction scheduledActionData) {
|
|
||||||
scheduledActionData.recordAndReset();
|
|
||||||
actionScheduler.schedule(Set.of(scheduledActionData));
|
|
||||||
} else {
|
|
||||||
executableAction.setStatus(Action.Status.SUCCESS);
|
|
||||||
}
|
|
||||||
// TODO 执行过后需要回写至任务上下文(recentCompletedTask),同时触发自对话信号进行确认并记录以及是否通知用户(触发与否需要机制进行匹配,在模块链路可增加 interaction gate 门控,判断此次对话作用于谁、由谁发出、何种性质、是否需要回应等)
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
boolean next() {
|
||||||
|
executingStageUpdated = false;
|
||||||
|
stageCountUpdated = false;
|
||||||
|
return stageCount < actionChain.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
val orderList = new ArrayList<>(actionChain.keySet());
|
||||||
|
orderList.sort(Integer::compareTo);
|
||||||
|
executableAction.setExecutingStage(orderList.get(stageCount));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
stageCursor.init();
|
||||||
|
do {
|
||||||
|
val metaActions = actionChain.get(executableAction.getExecutingStage());
|
||||||
|
val listeningRecord = executeAndListening(metaActions, phaserRecord, source);
|
||||||
|
phaser.awaitAdvance(listeningRecord.phase());
|
||||||
|
// synchronized 同步防止 accepting 循环间、phase guard 判定后发生 stage 推进
|
||||||
|
// 导致新行动的 phaser 投放阶段错乱无法阻塞的场景
|
||||||
|
// 该 synchronized 将阶段推进与 accepting 监听 loop 捆绑为互斥的原子事件,避免了细粒度的 phaser 阶段竞态问题
|
||||||
|
synchronized (listeningRecord.accepting()) {
|
||||||
|
listeningRecord.accepting().set(false);
|
||||||
|
// 立即尝试推进,本次推进中,如果前方仍有未执行 stage,将执行一次阶段推进
|
||||||
|
stageCursor.requestAdvance();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 针对行动链进行修正,修正需要传入执行历史、行动目标等内容
|
||||||
|
// 如果后续运行 corrector 触发频率较高,可考虑增加重试机制
|
||||||
|
val correctorInput = assemblyHelper.buildCorrectorInput(executableAction, source);
|
||||||
|
val correctorResult = actionCorrector.execute(correctorInput);
|
||||||
|
actionCapability.handleInterventions(correctorResult.getMetaInterventionList(), executableAction);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
// 第二次尝试进行阶段推进,本次负责补充上一次在不存在 stage时,但 corrector 执行期间发生了 actionChain 的插入事件
|
||||||
|
// 如果第一次已经推进完毕,本次将会跳过
|
||||||
|
stageCursor.requestAdvance();
|
||||||
|
} while (stageCursor.next());
|
||||||
|
// 结束
|
||||||
|
actionCapability.removePhaserRecord(phaser);
|
||||||
|
if (executableAction.getStatus() != Action.Status.FAILED) {
|
||||||
|
// 如果是 ScheduledActionData, 则重置 ActionData 内容,记录执行历史与最终结果
|
||||||
|
if (executableAction instanceof SchedulableExecutableAction scheduledActionData) {
|
||||||
|
scheduledActionData.recordAndReset();
|
||||||
|
actionScheduler.schedule(Set.of(scheduledActionData));
|
||||||
|
} else {
|
||||||
|
executableAction.setStatus(Action.Status.SUCCESS);
|
||||||
|
}
|
||||||
|
// TODO 执行过后需要回写至任务上下文(recentCompletedTask),同时触发自对话信号进行确认并记录以及是否通知用户(触发与否需要机制进行匹配,在模块链路可增加 interaction gate 门控,判断此次对话作用于谁、由谁发出、何种性质、是否需要回应等)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import work.slhaf.partner.core.memory.MemoryCapability;
|
|||||||
import work.slhaf.partner.core.perceive.PerceiveCapability;
|
import work.slhaf.partner.core.perceive.PerceiveCapability;
|
||||||
import work.slhaf.partner.module.common.module.PreRunningAbstractAgentModuleAbstract;
|
import work.slhaf.partner.module.common.module.PreRunningAbstractAgentModuleAbstract;
|
||||||
import work.slhaf.partner.module.modules.action.executor.ActionExecutor;
|
import work.slhaf.partner.module.modules.action.executor.ActionExecutor;
|
||||||
import work.slhaf.partner.module.modules.action.executor.entity.ActionExecutorInput;
|
|
||||||
import work.slhaf.partner.module.modules.action.planner.confirmer.ActionConfirmer;
|
import work.slhaf.partner.module.modules.action.planner.confirmer.ActionConfirmer;
|
||||||
import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerInput;
|
import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerInput;
|
||||||
import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerResult;
|
import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerResult;
|
||||||
@@ -154,8 +153,7 @@ public class ActionPlanner extends PreRunningAbstractAgentModuleAbstract {
|
|||||||
// execute or schedule it immediately
|
// execute or schedule it immediately
|
||||||
switch (executableAction) {
|
switch (executableAction) {
|
||||||
case SchedulableExecutableAction action -> actionScheduler.schedule(Set.of(action));
|
case SchedulableExecutableAction action -> actionScheduler.schedule(Set.of(action));
|
||||||
case ImmediateExecutableAction action ->
|
case ImmediateExecutableAction action -> actionExecutor.execute(action);
|
||||||
actionExecutor.execute(new ActionExecutorInput(Set.of(action)));
|
|
||||||
default -> log.error("unknown executable action type: {}", executableAction.getClass().getSimpleName());
|
default -> log.error("unknown executable action type: {}", executableAction.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,10 @@ import work.slhaf.partner.api.agent.factory.component.abstracts.AbstractAgentMod
|
|||||||
import work.slhaf.partner.api.agent.factory.component.annotation.Init
|
import work.slhaf.partner.api.agent.factory.component.annotation.Init
|
||||||
import work.slhaf.partner.api.agent.factory.component.annotation.InjectModule
|
import work.slhaf.partner.api.agent.factory.component.annotation.InjectModule
|
||||||
import work.slhaf.partner.core.action.ActionCapability
|
import work.slhaf.partner.core.action.ActionCapability
|
||||||
import work.slhaf.partner.core.action.ActionCore
|
import work.slhaf.partner.core.action.entity.Action
|
||||||
import work.slhaf.partner.core.action.entity.Schedulable
|
import work.slhaf.partner.core.action.entity.Schedulable
|
||||||
import work.slhaf.partner.core.action.entity.SchedulableExecutableAction
|
import work.slhaf.partner.core.action.entity.SchedulableExecutableAction
|
||||||
import work.slhaf.partner.core.action.entity.StateAction
|
|
||||||
import work.slhaf.partner.module.modules.action.executor.ActionExecutor
|
import work.slhaf.partner.module.modules.action.executor.ActionExecutor
|
||||||
import work.slhaf.partner.module.modules.action.executor.entity.ActionExecutorInput
|
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
@@ -54,17 +52,8 @@ class ActionScheduler : AbstractAgentModule.Standalone() {
|
|||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
}
|
}
|
||||||
val onTrigger: (Set<Schedulable>) -> Unit = { schedulableSet ->
|
val onTrigger: (Set<Schedulable>) -> Unit = { schedulableSet ->
|
||||||
val executableActions = mutableSetOf<SchedulableExecutableAction>()
|
schedulableSet.filterIsInstance<Action>()
|
||||||
val stateActions = mutableSetOf<StateAction>()
|
.forEach { actionExecutor.execute(it) }
|
||||||
for (schedulable in schedulableSet) {
|
|
||||||
when (schedulable) {
|
|
||||||
is SchedulableExecutableAction -> executableActions.add(schedulable)
|
|
||||||
is StateAction -> stateActions.add(schedulable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
actionExecutor.execute(ActionExecutorInput(executableActions))
|
|
||||||
actionCapability.getExecutor(ActionCore.ExecutorType.VIRTUAL)
|
|
||||||
.execute { stateActions.forEach { it.trigger.onTrigger() } }
|
|
||||||
}
|
}
|
||||||
timeWheel = TimeWheel(listScheduledActions, onTrigger)
|
timeWheel = TimeWheel(listScheduledActions, onTrigger)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import work.slhaf.partner.module.modules.action.executor.ActionCorrector;
|
|||||||
import work.slhaf.partner.module.modules.action.executor.ActionExecutor;
|
import work.slhaf.partner.module.modules.action.executor.ActionExecutor;
|
||||||
import work.slhaf.partner.module.modules.action.executor.ActionRepairer;
|
import work.slhaf.partner.module.modules.action.executor.ActionRepairer;
|
||||||
import work.slhaf.partner.module.modules.action.executor.ParamsExtractor;
|
import work.slhaf.partner.module.modules.action.executor.ParamsExtractor;
|
||||||
import work.slhaf.partner.module.modules.action.executor.entity.ActionExecutorInput;
|
|
||||||
import work.slhaf.partner.module.modules.action.executor.entity.CorrectorResult;
|
import work.slhaf.partner.module.modules.action.executor.entity.CorrectorResult;
|
||||||
import work.slhaf.partner.module.modules.action.executor.entity.ExtractorResult;
|
import work.slhaf.partner.module.modules.action.executor.entity.ExtractorResult;
|
||||||
import work.slhaf.partner.module.modules.action.executor.entity.RepairerResult;
|
import work.slhaf.partner.module.modules.action.executor.entity.RepairerResult;
|
||||||
@@ -97,7 +96,6 @@ class ActionExecutorTest {
|
|||||||
stubExecutors(directExecutor, directExecutor);
|
stubExecutors(directExecutor, directExecutor);
|
||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
ExtractorResult extractorResult = new ExtractorResult();
|
ExtractorResult extractorResult = new ExtractorResult();
|
||||||
extractorResult.setOk(true);
|
extractorResult.setOk(true);
|
||||||
@@ -109,7 +107,7 @@ class ActionExecutorTest {
|
|||||||
}).when(runnerClient).submit(any(MetaAction.class));
|
}).when(runnerClient).submit(any(MetaAction.class));
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
verify(runnerClient, times(1)).submit(any(MetaAction.class));
|
verify(runnerClient, times(1)).submit(any(MetaAction.class));
|
||||||
verify(actionCapability, times(1)).removePhaserRecord(any(Phaser.class));
|
verify(actionCapability, times(1)).removePhaserRecord(any(Phaser.class));
|
||||||
@@ -125,10 +123,9 @@ class ActionExecutorTest {
|
|||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
||||||
actionData.setStatus(ExecutableAction.Status.EXECUTING);
|
actionData.setStatus(ExecutableAction.Status.EXECUTING);
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
verify(actionCapability, never()).putPhaserRecord(any(Phaser.class), any(ExecutableAction.class));
|
verify(actionCapability, never()).putPhaserRecord(any(Phaser.class), any(ExecutableAction.class));
|
||||||
verify(runnerClient, never()).submit(any(MetaAction.class));
|
verify(runnerClient, never()).submit(any(MetaAction.class));
|
||||||
@@ -145,7 +142,6 @@ class ActionExecutorTest {
|
|||||||
chain.put(0, List.of(buildMetaAction("a1", false)));
|
chain.put(0, List.of(buildMetaAction("a1", false)));
|
||||||
chain.put(1, List.of(buildMetaAction("a2", false)));
|
chain.put(1, List.of(buildMetaAction("a2", false)));
|
||||||
ImmediateExecutableAction actionData = buildActionData(chain);
|
ImmediateExecutableAction actionData = buildActionData(chain);
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
ExtractorResult extractorResult = new ExtractorResult();
|
ExtractorResult extractorResult = new ExtractorResult();
|
||||||
extractorResult.setOk(true);
|
extractorResult.setOk(true);
|
||||||
@@ -158,7 +154,7 @@ class ActionExecutorTest {
|
|||||||
}).when(runnerClient).submit(any(MetaAction.class));
|
}).when(runnerClient).submit(any(MetaAction.class));
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
verify(runnerClient, timeout(5000).times(2)).submit(any(MetaAction.class));
|
verify(runnerClient, timeout(5000).times(2)).submit(any(MetaAction.class));
|
||||||
verify(actionCorrector, timeout(5000).times(2)).execute(any());
|
verify(actionCorrector, timeout(5000).times(2)).execute(any());
|
||||||
@@ -174,7 +170,6 @@ class ActionExecutorTest {
|
|||||||
stubExecutors(platformExecutor, virtualExecutor);
|
stubExecutors(platformExecutor, virtualExecutor);
|
||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(singleStageChain(true));
|
ImmediateExecutableAction actionData = buildActionData(singleStageChain(true));
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
ExtractorResult extractorResult = new ExtractorResult();
|
ExtractorResult extractorResult = new ExtractorResult();
|
||||||
extractorResult.setOk(true);
|
extractorResult.setOk(true);
|
||||||
@@ -186,7 +181,7 @@ class ActionExecutorTest {
|
|||||||
}).when(runnerClient).submit(any(MetaAction.class));
|
}).when(runnerClient).submit(any(MetaAction.class));
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
verify(actionCapability, times(1)).getExecutor(ActionCore.ExecutorType.VIRTUAL);
|
verify(actionCapability, times(1)).getExecutor(ActionCore.ExecutorType.VIRTUAL);
|
||||||
shutdownExecutor(virtualExecutor);
|
shutdownExecutor(virtualExecutor);
|
||||||
@@ -200,7 +195,6 @@ class ActionExecutorTest {
|
|||||||
stubExecutors(platformExecutor, virtualExecutor);
|
stubExecutors(platformExecutor, virtualExecutor);
|
||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
ExtractorResult fail = new ExtractorResult();
|
ExtractorResult fail = new ExtractorResult();
|
||||||
fail.setOk(false);
|
fail.setOk(false);
|
||||||
@@ -220,7 +214,7 @@ class ActionExecutorTest {
|
|||||||
}).when(runnerClient).submit(any(MetaAction.class));
|
}).when(runnerClient).submit(any(MetaAction.class));
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
@@ -238,7 +232,6 @@ class ActionExecutorTest {
|
|||||||
stubExecutors(platformExecutor, virtualExecutor);
|
stubExecutors(platformExecutor, virtualExecutor);
|
||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
ExtractorResult fail = new ExtractorResult();
|
ExtractorResult fail = new ExtractorResult();
|
||||||
fail.setOk(false);
|
fail.setOk(false);
|
||||||
@@ -249,13 +242,13 @@ class ActionExecutorTest {
|
|||||||
when(actionRepairer.execute(any())).thenReturn(repairerResult);
|
when(actionRepairer.execute(any())).thenReturn(repairerResult);
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
}
|
}
|
||||||
MetaAction metaAction = actionData.getActionChain().get(0).get(0);
|
MetaAction metaAction = actionData.getActionChain().get(0).getFirst();
|
||||||
assertEquals(MetaAction.Result.Status.FAILED, metaAction.getResult().getStatus());
|
assertEquals(MetaAction.Result.Status.FAILED, metaAction.getResult().getStatus());
|
||||||
verify(runnerClient, never()).submit(any(MetaAction.class));
|
verify(runnerClient, never()).submit(any(MetaAction.class));
|
||||||
}
|
}
|
||||||
@@ -269,7 +262,6 @@ class ActionExecutorTest {
|
|||||||
stubExecutors(platformExecutor, virtualExecutor);
|
stubExecutors(platformExecutor, virtualExecutor);
|
||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
ExtractorResult fail = new ExtractorResult();
|
ExtractorResult fail = new ExtractorResult();
|
||||||
fail.setOk(false);
|
fail.setOk(false);
|
||||||
@@ -305,7 +297,7 @@ class ActionExecutorTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
assertTrue(doneLatch.await(2, TimeUnit.SECONDS));
|
assertTrue(doneLatch.await(2, TimeUnit.SECONDS));
|
||||||
shutdownExecutor(platformExecutor);
|
shutdownExecutor(platformExecutor);
|
||||||
@@ -323,7 +315,6 @@ class ActionExecutorTest {
|
|||||||
stubExecutors(platformExecutor, virtualExecutor);
|
stubExecutors(platformExecutor, virtualExecutor);
|
||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
ImmediateExecutableAction actionData = buildActionData(singleStageChain(false));
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
ExtractorResult ok = new ExtractorResult();
|
ExtractorResult ok = new ExtractorResult();
|
||||||
ok.setOk(true);
|
ok.setOk(true);
|
||||||
@@ -337,7 +328,7 @@ class ActionExecutorTest {
|
|||||||
lenient().doThrow(new RuntimeException("boom")).when(actionCorrector).execute(any());
|
lenient().doThrow(new RuntimeException("boom")).when(actionCorrector).execute(any());
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
@@ -356,10 +347,9 @@ class ActionExecutorTest {
|
|||||||
stubExecutors(platformExecutor, virtualExecutor);
|
stubExecutors(platformExecutor, virtualExecutor);
|
||||||
|
|
||||||
ImmediateExecutableAction actionData = buildActionData(new HashMap<>());
|
ImmediateExecutableAction actionData = buildActionData(new HashMap<>());
|
||||||
ActionExecutorInput input = buildInput("u1", actionData);
|
|
||||||
|
|
||||||
actionExecutor.init();
|
actionExecutor.init();
|
||||||
actionExecutor.execute(input);
|
actionExecutor.execute(actionData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
@@ -373,10 +363,6 @@ class ActionExecutorTest {
|
|||||||
when(actionCapability.runnerClient()).thenReturn(runnerClient);
|
when(actionCapability.runnerClient()).thenReturn(runnerClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ActionExecutorInput buildInput(String userId, ImmediateExecutableAction actionData) {
|
|
||||||
return new ActionExecutorInput(Set.of(actionData));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ImmediateExecutableAction buildActionData(Map<Integer, List<MetaAction>> actionChain) {
|
private ImmediateExecutableAction buildActionData(Map<Integer, List<MetaAction>> actionChain) {
|
||||||
val immediateActionData = new ImmediateExecutableAction(
|
val immediateActionData = new ImmediateExecutableAction(
|
||||||
"tendency",
|
"tendency",
|
||||||
|
|||||||
Reference in New Issue
Block a user