Skip to content

Document the difference between an event-driven schedule and a startup listen task #987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
19 changes: 19 additions & 0 deletions dsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- [Components](#components)
+ [Task](#task)
- [Scheduling](#scheduling)
+ [Event-Driven Scheduling](#event-driven-scheduling)
+ [Task Flow](#task-flow)
+ [Data Flow](#data-flow)
+ [Runtime Expressions](#runtime-expressions)
Expand Down Expand Up @@ -150,6 +151,24 @@ Workflow scheduling in ServerlessWorkflow allows developers to specify when and

See the [DSL reference](dsl-reference.md#schedule) for more details about workflow scheduling.

##### Event-driven scheduling

###### Input of event-driven scheduled workflows

In event-driven scheduled workflows, the input is structured as an array containing the events that trigger the execution of the workflow. This array serves as a vital resource, providing workflow authors access to all relevant data associated with each triggering event. When an event activates the workflow, it populates this array with one or more occurrences, allowing authors to process multiple events simultaneously as needed.

Authors can reference individual events within the array using syntax such as $workflow.input[index], where index indicates the event's position, starting from 0. For instance, $workflow.input[0] refers to the first event, while $workflow.input[1] refers to the second. This structure allows for easy access to specific event details, and if multiple events are received at once, authors can iterate through the array to handle each one appropriately. This flexibility ensures that workflows can respond effectively to various conditions and triggers, enhancing their overall responsiveness and functionality.

###### Distinguishing event-driven scheduling from start `listen` Tasks

While both `schedule.on` and a start listener task enable event-driven execution of workflows, they serve distinct purposes and have different implications:

- **`schedule.on`**: This property defines when a new workflow instance should be created based on an external event. When an event matches the criteria specified in `schedule.on`, a new workflow instance is initiated. The critical point here is that `schedule.on` solely manages the creation of new workflow instances. Any faults or timeouts related to the scheduling process are typically invisible to the user and do not impact the workflow instance.

- **Start `listen` task**: A start listener task defines a task that must be undertaken after a new workflow instance has been created. This task listens for specific events and begins processing once the instance is active. The critical difference is that a start listener task operates within an already instantiated workflow. If a start listener task experiences a timeout or fault, it can cause the entire workflow instance to fail or behave unexpectedly, directly impacting the flow's execution and outcome.

While `schedule.on` is concerned with *when* a new workflow instance should be initiated, a start listener task deals with *what* should happen once the instance is active. This distinction is crucial because it influences how errors and timeouts are handled—`schedule.on` faults are typically invisible and do not affect the workflow, whereas start listener task failures can directly and potentially severely impact the workflow instance they belong to.

### Task Flow

A workflow begins with the first task defined.
Expand Down
13 changes: 13 additions & 0 deletions examples/cron-schedule.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
document:
dsl: 1.0.0-alpha1
namespace: examples
name: cron-schedule
version: 1.0.0-alpha1
schedule:
cron: 0 0 * * *
do:
- backup:
call: http
with:
method: post
endpoint: https://example.com/api/v1/backup/start
24 changes: 24 additions & 0 deletions examples/event-driven-schedule.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
document:
dsl: 1.0.0-alpha1
namespace: examples
name: event-driven-schedule
version: 1.0.0-alpha1
schedule:
on:
one:
with:
type: com.example.hospital.events.patients.heartbeat.low
do:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have to use a listener task instead in this example?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on what you want to achieve.

The objective here is to trigger a new workflow when and only when the event is received.

Using a listen task would mean you'd have started a workflow out of the blue, then wait potentially forever for an event to be consumed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on our private conversation, we agreed to follow up with an issue to review the schedule.on naming since it may confuse users. Some may expect that schedule enforces a timestamp definition.

- callNurse:
call: http
with:
method: post
endpoint: https://hospital.example.com/api/v1/notify
body:
patientId: ${ $workflow.input[0].data.patient.id }
patientName: ${ $workflow.input[0].data.patient.name }
roomNumber: ${ $workflow.input[0].data.patient.room.number }
vitals:
heartRate: ${ $workflow.input[0].data.patient.vitals.bpm }
timestamp: ${ $workflow.input[0].data.timestamp }
message: "Alert: Patient's heartbeat is critically low. Immediate attention required."
Loading