Implementing Workflow Patterns

This section demonstrates how to implement common workflow patterns using the AWS Flow Framework for Ruby. Much more information about commonly-used workflow patterns can be found on the Workflow Patterns page, presented by the Eindhoven and Queensland Universities of Technology.

Sequence#

_images/wp-sequence.png

A sequence pattern refers to a workflow in which one task follows another in sequential order. It is implemented by calling activities synchronously:

client.activity1
client.activity2
client.activity3

Since each activity blocks execution of the main thread when it runs, activity2 will run only after activity1 has completed. Likewise, activity3 won't run until after activity2 is complete.

Parallel Split#

_images/wp-parallel-split.png

A parallel split pattern refers to a workflow in which one or more tasks are executed concurrently. It is implemented by calling activities asynchronously with GenericClient#send_async:

client.activity1
client.send_async(:activity2)
client.send_async(:activity3)

The send_async method launches a fiber to run the activity on and returns immediately. In this case, activity3 will be run immediately, without waiting for activity2 to complete. Likewise, execution of the main thread will continue without waiting for either activity2 or activity3 to complete.

If you want your main thread to wait for one or both activities to finish before proceeding, see simple merge or synchronization.

Synchronization#

_images/wp-synchronize.png

A synchronization pattern refers to a workflow in which the main thread waits for one or more concurrently-running tasks to complete before continuing. It is implemented by calling Core#wait_for_all with the futures that are returned from the activities that you want to synchronize:

first_future = client.send_async(:activity1)
second_future = client.send_async(:activity2)
wait_for_all(first_future, second_future)
client.activity3

Exclusive Choice#

_images/wp-exclusive-choice.png

An exclusive choice pattern refers to a workflow in which the results of one activity are used to select one subsequent activity to run from a set of two or more activities. It is implemented by choosing the activity to run based on the value returned by a predicate function acting on a decision value:

decision_value = client.activity1
if (predicate_function(decision_value))
  client.activity2
else
  client.activity3
end

Simple Merge#

_images/wp-simple-merge.png

A simple merge pattern refers to a workflow in which the completion of one or more activities triggers the next activity in the sequence. It is implemented by calling Core#wait_for_any with the futures that are returned from the activities that you want to merge:

first_future = client.send_async(:activity1)
second_future = client.send_async(:activity2)
wait_for_any(first_future, second_future)
client.activity3

Multi Choice#

_images/wp-multi-choice.png

A multi choice pattern refers to a workflow in which the results of one activity are used to select one or more subsequent activities to run from a set of two or more activities. This is very similar to exclusive choice, but more than one branch in the workflow may be run. Like exclusive choice, it is commonly implemented with a predicate function that chooses one or more activities to run based on a decision value:

decision_value = client.activity1
if (predicate_function(decision_value))
  client.activity2
elsif (predicate_function2(decision_value))
  client.activity3
else
  client.send_async(:activity3)
  client.send_async(:activity4)
end