Introduction
Hatchet V1 introduces the ability to add conditions to tasks in your workflows that determine whether or not a task should be run, based on a number of conditions. There are three types of Condition
s in Hatchet V1:
- Sleep conditions, which sleep for a specified duration before continuing
- Event conditions, which wait for an event (and optionally a CEL expression evaluated on the payload of that event) before deciding how to continue
- Parent conditions, which wait for a parent task to complete and then decide how to progress based on its output.
These conditions can also be combined using an Or
operator into groups of conditions where at least one must be satisfied in order for the group to evaluate to True
.
Conditions can be used at task declaration time in three ways:
- They can be used in a
wait_for
fashion, where a task will wait for the conditions to evaluate toTrue
before being run. - They can be used in a
skip_if
fashion, where a task will be skipped if the conditions evaluate toTrue
. - They can be used in a
cancel_if
fashion, where a task will be cancelled if the conditions evaluate toTrue
.
Use Cases
There are a number of use cases that these features unlock. Some examples might be:
- A workflow that reads a feature flag, and then decides how to progress based on its value. In this case, you’d have two tasks that use parent conditions, where one task runs if the flag value is e.g.
True
, while the other runs if it’sFalse
. - Any type of human-in-the-loop workflow, where you want to wait for a human to e.g. approve something before continuing the run.
Example Workflow
In this example, we’re going to build the following workflow:
Note the branching logic (left_branch
and right_branch
), as well as the use of skips and waits.
To get started, let’s declare the workflow.
Next, we’ll start adding tasks to our workflow. First, we’ll add a basic task that outputs a random number:
Next, we’ll add a task to the workflow that’s a child of the first task, but it has a wait_for
condition that sleeps for 10 seconds.
This task will first wait for the parent task to complete, and then it’ll sleep for 10 seconds before executing and returning another random number.
Next, we’ll add a task that will be skipped on an event:
In this case, our task will wait for a 30 second sleep, and then it will be skipped if the skip_on_event:skip
is fired.
Next, let’s add some branching logic. Here we’ll add two more tasks, a left and right branch.
These two tasks use the ParentCondition
and skip_if
together to check if the output of an upstream task was greater or less than 50
, respectively. Only one of the two tasks will run: whichever one’s condition evaluates to True
.
Next, we’ll add a task that waits for an event:
And finally, we’ll add the last task, which collects all of its parents and sums them up.
Note that in this task, we rely on ctx.was_skipped
to determine if a task was skipped.
This workflow demonstrates the power of the new conditional logic in Hatchet V1. You can now create complex workflows that are much more dynamic than workflows in the previous version of Hatchet, and do all of it declaratively (rather than, for example, by dynamically spawning child workflows based on conditions in the parent).