The difference between a function_node
accepting a continue_msg
input and a continue_node
is the behavior when receiving a message. This is a consequence of the concept of "dependence graph."
The idea of dependence graphs is that the only information being passed by the graph is the completion of a task. If you have four tasks (A,B,C,D) all operating on the same shared data, and tasks A and B must be complete before either C or D can be started, you define four continue_nodes
, and attach the output of node A to C and D, and the same for B. You may also create a broadcast_node<continue_msg>
and attach A and B as successors to it. (The data being used in the computation must be accessible by some other means.)

To start the graph you do a try_put
of a continue_msg
to the broadcast_node
. The broadcast_node
sends a continue_msg
to each successor (A & B).
continue_nodes
A and B each have 1 predecessor (the broadcast_node
.) On receiving a number of continue_msgs
equal to their predecessor count (1), they are queued to execute, using and updating the data representing the state of the computation.
When continue_node
A completes, it sends a continue_msg
to each successor, C & D. Those nodes each have two predecessors, so they do not execute on receiving this message. They only remember they have received one message.
When continue_node
B completes, it also sends a continue_msg
to C and D. This will be the second continue_msg
each node receives, so tasks will be queued to execute their function_bodies.
continue_nodes
use the graph only to express this order. No data is transferred from node to node (beyond the signal that a predecessor is complete.)
If the nodes in the graph were function_nodes
accepting continue_msgs
rather than continue_nodes
, the reaction to the broadcast_node
getting a continue_msg
would be
- The
broadcast_node
would forward a continue_msg
to A and B, and they would each execute their function_bodies.
- Node A would complete, and pass
continue_msgs
to C and D.
- On receiving the
continue_msg
, tasks would be queued to execute the function_bodies of C and D.
- Node B would complete execution, and forward a
continue_msg
to C and D.
- C and D, on receiving this second continue_msg, would queue a task to execute their function_bodies a second time.
Notice 3. above. The function_node
reacts each time it receives a continue_msg
. The continue_node
knows how many predecessors it has, and only reacts when it receives a number of continue_msgs
equal to its number of predecessors.
The dependence graph is convenient if there is a lot of state being used in the computation, and if the sequence of tasks is well understood. The idea of "shared state" does not necessarily dictate the use of a dependence graph, but a dependence graph cannot pass anything but completion state of the work involved, and so must use shared state to communicate other data.
(Note that the completion order I am describing above is only one possible ordering. Node B could complete before node A, but the sequence of actions would be similar.)