Waiting Within a Workflow


The wait function pauses the execution of a workflow until a duration or event. It’s easy to wait from a workflow, using the this.wait function:

module.exports.handle = function* (...input) {
  ...
  yield this.run.task("taskA", ...inputA);
  yield this.wait.for(3600);
  yield this.run.task("taskB", ...inputB);
  ...
};

Here, we will wait one hour (3600 seconds) after the completion of taskA and before the dispatch of taskB.

WARNING

Do not forget the yield keyword! Without it, the wait instruction is processed in the background and the workflow continues immediately to the next instructions.

# Wait Duration

In order to wait s seconds between two tasks, add this between those tasks:

yield this.wait.for(s);

Per default, duration are in seconds. For larger values, Zenaton provides a duration helper. For example, in order to wait for 2 weeks, just add this:

const { duration } = require("zenaton");

module.exports.handle = function* (...) {
  ...
  yield. this.wait.for(duration.weeks(2));
  ...
};

Your workflow will continue its processing 2 weeks later (at the same time). There are numerous options to fine-tune the waiting duration:

METHOD ACTION
.seconds(30) waits 30 seconds
.minutes(15) waits 15 minutes
.hours(2) waits 2 hours
.days(1) waits 1 day
.weeks(1) waits next week (same time)
.months(2) waits 2 months (same time)
.years(10) waits 10 years (same time)

These methods can also be combined, e.g.,

yield this.wait.for(duration.weeks(2).hours(2).minutes(15).seconds(23));

will wait for exactly 14 days, 2 hours, 15 minutes and 23 seconds.

# Wait Date

In order to wait up to a specific timestamp ts, just add this between those tasks:

yield this.wait.until(ts);

For more clarity, Zenaton provides a datetime helper. For example, in order to wait until next monday (same time), add:

const { datetime } = require("zenaton");

module.exports.handle = function* (...) {
  ...
  yield.this.wait.until(datetime.monday());
  ...
};
METHOD ACTION
.at("15:10:23") waits until 3:10PM and 23 seconds
.dayOfMonth(12) waits to next 12th day (same time)
.monday() waits to next Monday (same time)
.tuesday(1) waits to next Tuesday (same time)
.wednesday(2) waits to 2nd Wednesday (same time)
.thursday() waits to next Thursday (same time)
.friday() waits to next Friday (same time)
.saturday() waits to next Saturday (same time)
.sunday() waits to next Sunday (same time)

These methods can be combined, e.g.,

yield this.wait.until(datetime.monday().at("8:00"));

will wait until next Monday at 8am.

If you are on Monday, at 7am, this will wait for an hour only. If you are on Monday, at 9am, it will wait for a week minus one hour.

In order to define another timezone than the default one, just use the timezone method in the duration. Eg.

yield this.wait.until(datetime.timezone('Europe/Paris').monday().at("8:00"));

# Wait for an Event

You can wait for an event in order to trigger the next action when the event occurs.

const event = yield this.wait.event("<event name>").forever();

In this example, the workflow will wait for the specific event. Then event contains [<event name>, ...<event data>].

# Wait for an Event until a Time

You can add a timeone into the wait function that will specify how long the workflow should wait. If the event is not received within the specified time, it will continue.

This allows:

a way to trigger an action if an event does not happen within the specified time or the workflow to terminate if the event is never received

const event = yield this.wait.event("<event name>").for(5*24*60*60);

In this example, after 5 days without event, the execution of the workflow will be released, but event will be undefined. You can use the same methods as above to define the duration or the date of this timeout.

WARNING

If a workflow has received an event "<event name>" before having reached the corresponding this.wait.event("<event name>") instruction, this event will be ignored. And the workflow will wait for this event again when reaching the instruction. If this is not the behavior you want, please consider the persistent event pattern.