Skip to content

Delayed messages: reminders with timers

Ask for a review a day after checkout: a timer keyed by the booking is scheduled, moved or cancelled, and fires as a real message in the booking's partition.

Updated View as Markdown

A day after an order is delivered, ask for a review. If the delivery is late, move the reminder. If the guest already wrote a review, cancel it. The usual answer is a cron job that scans a table every minute.

A timer is a message that waits. It is named by its queue and a key: scheduling the same key again moves it, and cancelling the key removes it. When it is due, it arrives in its queue as a normal message, through the log.

A timeline for the reminder review-2001 in the queue review-reminders. Scheduled at delivery for 24 hours later: status scheduled. The delivery is late, so the same key is scheduled again for 48 hours: status rescheduled, and the first time is gone. The guest writes a review, so the key is cancelled. A timer that is not cancelled fires as a normal message of its queue, through the log.A timeline for the reminder review-2001 in the queue review-reminders. Scheduled at delivery for 24 hours later: status scheduled. The delivery is late, so the same key is scheduled again for 48 hours: status rescheduled, and the first time is gone. The guest writes a review, so the key is cancelled. A timer that is not cancelled fires as a normal message of its queue, through the log.
A keyed timer: schedule, move, cancel.
// When an order is delivered, ask for a review in 24 hours.
await queen.timer('review-reminders').key('review-2001').delay('24h')
  .payload({ orderId: 2001 }).schedule()          // status: 'scheduled'

// The delivery was late: schedule the same key again, and the reminder moves.
await queen.timer('review-reminders').key('review-2001').delay('48h')
  .payload({ orderId: 2001 }).schedule()          // status: 'rescheduled'

// The guest wrote a review already: no reminder at all.
await queen.timer('review-reminders').key('review-2001').cancel()

The first call answered scheduled and the second rescheduled; after the cancel, no reminder was left. A short timer of the same queue arrived as a message, with its payload as data.

Why
the key makes a reminder easy to move or cancel, and a retried schedule is harmless. Put the timer in the transaction of the step that creates it, and it exists exactly when the step committed.

One thing to know: a cancel can arrive just after the timer fired. The consumer of the reminder should check the order’s state before it sends anything.

Built from: KV, locks and timers.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close