[ONOS-7732] Automating switch workflow - program counter refactoring

Change-Id: Ic5271121dad45222ded24ea41dbb2f5efba1ff2e
This commit is contained in:
jaegonkim 2019-04-21 11:10:25 +09:00
parent 2d77c1a049
commit f85ee3c201
4 changed files with 54 additions and 16 deletions

View File

@ -74,32 +74,31 @@ public final class ImmutableListWorkflow extends AbstractWorkflow {
return getWorkletInstance(initWorkletType);
}
@Override
public ProgramCounter next(WorkflowContext context) throws WorkflowException {
int cnt = 0;
ProgramCounter pc = context.current();
check(pc != null, "Invalid program counter");
ProgramCounter current = context.current();
check(current != null, "Invalid program counter");
for (int i = pc.workletIndex(); i < workletTypeList.size(); i++) {
ProgramCounter pc = current.clone();
for (int i = current.workletIndex(); i < workletTypeList.size(); pc = increased(pc), i++) {
if (cnt++ > Worklet.MAX_WORKS) {
throw new WorkflowException("Maximum worklet execution exceeded");
}
String workletType = workletTypeList.get(i);
if (Worklet.Common.COMPLETED.tag().equals(workletType)) {
return ProgramCounter.valueOf(workletType, i);
if (pc.isCompleted()) {
return pc;
}
if (Worklet.Common.INIT.tag().equals(workletType)) {
if (pc.isInit()) {
continue;
}
Worklet worklet = getWorkletInstance(workletType);
Worklet worklet = getWorkletInstance(pc);
Class workClass = worklet.getClass();
if (BranchWorklet.class.isAssignableFrom(workClass)) {
@ -121,11 +120,12 @@ public final class ImmutableListWorkflow extends AbstractWorkflow {
// isNext is read only. It does not perform 'inhale'.
dataModelInjector.inject(worklet, context);
if (worklet.isNext(context)) {
return ProgramCounter.valueOf(workletType, i);
return pc;
}
}
}
throw new WorkflowException("workflow reached to end but not COMPLETED");
throw new WorkflowException("workflow reached to end but not COMPLETED (pc:"
+ current + ", workflow:" + this.toString());
}
@Override
@ -140,6 +140,12 @@ public final class ImmutableListWorkflow extends AbstractWorkflow {
return ProgramCounter.valueOf(workletType, increaedIndex);
}
@Override
public Worklet getWorkletInstance(ProgramCounter pc) throws WorkflowException {
return getWorkletInstance(workletTypeList.get(pc.workletIndex()));
}
@Override
public Worklet getWorkletInstance(String workletType) throws WorkflowException {

View File

@ -62,6 +62,30 @@ public final class ProgramCounter {
this.workletIndex = workletIndex;
}
/**
* Clones this workflow Program Counter.
* @return clone of this workflow Program Counter
*/
public ProgramCounter clone() {
return ProgramCounter.valueOf(this.workletType(), this.workletIndex());
}
/**
* Returns whether this program counter is INIT worklet program counter.
* @return whether this program counter is INIT worklet program counter
*/
public boolean isInit() {
return Worklet.Common.INIT.tag().equals(this.workletType);
}
/**
* Returns whether this program counter is COMPLETED worklet program counter.
* @return whether this program counter is COMPLETED worklet program counter
*/
public boolean isCompleted() {
return Worklet.Common.COMPLETED.tag().equals(this.workletType);
}
@Override
public int hashCode() {
return Objects.hash(this.toString());

View File

@ -54,6 +54,14 @@ public interface Workflow {
*/
ProgramCounter increased(ProgramCounter pc) throws WorkflowException;
/**
* Returns instance of worklet.
* @param pc program counter
* @return instance of worklet
* @throws WorkflowException workflow exception
*/
Worklet getWorkletInstance(ProgramCounter pc) throws WorkflowException;
/**
* Returns instance of worklet.
* @param workletType class name of worklet

View File

@ -472,7 +472,7 @@ public class WorkFlowEngine extends AbstractListenerManager<WorkflowDataEvent, W
return task;
}
Worklet worklet = workflow.getWorkletInstance(task.programCounter().workletType());
Worklet worklet = workflow.getWorkletInstance(task.programCounter());
if (Worklet.Common.COMPLETED.equals(worklet) || Worklet.Common.INIT.equals(worklet)) {
log.error("Current worklet is {}, Ignored", worklet);
return task;
@ -562,7 +562,7 @@ public class WorkFlowEngine extends AbstractListenerManager<WorkflowDataEvent, W
return task;
}
Worklet worklet = workflow.getWorkletInstance(task.programCounter().workletType());
Worklet worklet = workflow.getWorkletInstance(task.programCounter());
if (worklet == Worklet.Common.COMPLETED || worklet == Worklet.Common.INIT) {
log.error("execEventTimeoutTask: Current worklet is {}, Ignored", worklet);
return task;
@ -632,7 +632,7 @@ public class WorkFlowEngine extends AbstractListenerManager<WorkflowDataEvent, W
return task;
}
Worklet worklet = workflow.getWorkletInstance(task.programCounter().workletType());
Worklet worklet = workflow.getWorkletInstance(task.programCounter());
if (worklet == Worklet.Common.COMPLETED || worklet == Worklet.Common.INIT) {
log.error("execTimeoutTask: Current worklet is {}, Ignored", worklet);
return task;
@ -736,7 +736,7 @@ public class WorkFlowEngine extends AbstractListenerManager<WorkflowDataEvent, W
try {
final ProgramCounter pc = workflow.next(latestContext);
final Worklet worklet = workflow.getWorkletInstance(pc.workletType());
final Worklet worklet = workflow.getWorkletInstance(pc);
if (worklet == Worklet.Common.INIT) {
log.error("workflow.next gave INIT. It cannot be executed (context: {})", context.name());