A Countdown powered by the Resonate Typescript SDK. The countdown sends notifications to ntfy.sh, a simple HTTP-based notification service, at configurable intervals.
The Countdown is implemented with Resonate's Durable Execution framework, Distributed Async Await. The Countdown is a simple loop that can sleep for hours, days, or weeks. On yield ctx.sleep the countdown function suspends, and after the specified delay, Resonate will resume the countdown function.
export function* countdown(
ctx: Context,
count: number,
delay: number,
url: string,
) {
for (let i = count; i > 0; i--) {
// send notification to ntfy.sh
yield* ctx.run(notify, url, `Countdown: ${i}`);
// sleep creates a suspension point
yield* ctx.sleep(delay * 60 * 1000);
}
// send the last notification to ntfy.sh
yield* ctx.run(notify, url, `Done`);
}Try yourself: Between notifications, kill the worker and restart. The countdown won't be affected and picks up exactly where it left off.
Install the Resonate Server
brew install resonatehq/tap/resonate
Clone the repository
git clone https://github.com/resonatehq-examples/resonate-countdown-ts.gitInstall dependencies
npm installIn Termainl #1, start the Resonate server in development mode listening on http://localhost:8001.
resonate dev- When you start the server in development mode, the server does not persist data on disk and lose its state when you stop the process
In Termainl #2, start the Resonate worker:
npm startIn Termainl #3, start the countdown, for example, counting down from 5, every minute, and posting notifications to https://ntfy.sh/resonatehq:
resonate invoke countdown.1 --func countdown --arg 5 --arg 1 --arg https://ntfy.sh/resonatehqParameters:
countdown.1: Unique ID for this countdown--arg 5: Count down from 5--arg 1: Wait 1 minute between counts--arg https://ntfy.sh/resonatehq: Where to send notifications
Open https://ntfy.sh/resonatehq in your browser to see the notifications in real-time.
Get details of a specific countdown:
resonate promises get countdown.1View all promises:
resonate promises search "*"
