Control Flow

Brainslug Flow Node Types

Task Node

A Task Node will be executed for every incoming token and produces one token per outgoing edge. See the [task documentation](task) for details on how to define what a task should do during execution.

single_task

Event Node

An Event Node is triggered by every incoming token and produces one token per outgoing edge. There are different type of event: Start Events, End Events, Wait (Intermediate) Events.

Example
class EventFlow extends FlowBuilder {

  Identifier eventFlowId = id("helloFlow");

  EventDefinition eventFlowStart = event(id("start")).display("Every 5 Seconds");

  EventDefinition fiveSecondsElapsed = event(id("wait")).display("After 5 Seconds")
    .elapsedTime(5, TimeUnit.SECONDS);

  TaskDefinition theTask = task(id("doIt")).display("Do Something");

  @Override
  public void define() {
    flowId(eventFlowId);

    start(eventFlowStart, every(5, TimeUnit.SECONDS))
      .waitFor(fiveSecondsElapsed)
      .execute(theTask);
  }
}
event_flow

Start Events mark the start of a flow and are generally the starting point of your flow definition. The waitFor-method takes an event definition which might have duration to wait for and create a intermediate event for it.

End Events mark the end of a flow execution path and are optional.

Choice Node

A Choice Node will be executed for every incoming token. A token is produced for the first outgoing path where the predicate is fullfilled.

Merge Node

A Merge Node merges different execution paths. It will be executed for every incoming token. A token is produced for every outgoing edge.

Example
class ChoiceFlow extends FlowBuilder {

  Identifier choiceFlowId = id("choiceFlow");

  EventDefinition choiceFlowStart = event(id("start"));
  EventDefinition choiceEnd = event(id("end")).display("end");

  Identifier meaningOfLiveChoice = id("meaning_choice");
  Expression meaningProperty = property(id("meaning"));

  EqualDefinition<?,?> equalsFortyTwo = eq(meaningProperty, 42);
  EqualDefinition<?,?> equalsFortyThree = eq(meaningProperty, 43);

  TaskDefinition meaningfulTask = task(id("meaning_ful")).display("Meaningful Task");
  TaskDefinition meaninglessTask = task(id("meaning_less")).display("Meaningless Task");

  @Override
  public void define() {
    flowId(choiceFlowId);

    start(choiceFlowStart)
      .choice(meaningOfLiveChoice).display("Meaning of live?")
        .when(equalsFortyTwo)
          .execute(meaningfulTask)
        .or()
        .when(equalsFortyThree)
          .execute(meaninglessTask);

    merge(meaningfulTask, meaninglessTask)
      .end(choiceEnd);
  }
}
choice_flow

Parallel Node

A Parallel Node defines flow paths which are meant for parallel execution, if the execution is really concurrent depends on the configuration of the corresponding FlowNodeExecutor. It will be executed for every incoming token. A token is produced for every outgoing edge.

Join Node

A Parallel Node joins or synchronizes multiple concurrent execution paths. It will only be executed if it has tokens from every incoming edge. A token is produced for every outgoing edge.

Example
class ParallelFlow extends FlowBuilder {

  Identifier parallelFlowId = id("parallel_flow");

  EventDefinition flowStart = event(id("start"));
  EventDefinition flowEnd = event(id("end")).display("end");

  TaskDefinition firstTask = task(id("first_task")).display("Do Something");
  TaskDefinition secondTask = task(id("second_task")).display("Do another Thing");

  @Override
  public void define() {
    flowId(parallelFlowId);

    start(flowStart)
      .parallel(id())
        .execute(firstTask)
          .and()
        .execute(secondTask);

    join(firstTask, secondTask)
      .end(flowEnd);
  }
}
parallel_flow