Skip to content

Countdown — Resonate

Countdown | Resonate Java SDK

A durable countdown that posts a notification on each tick and sleeps between ticks. Demonstrates ctx.run durable steps and ctx.sleep against a Resonate dev server.

Heads up — resonate-sdk-java is pre-release (v0.1.x). This example pins io.resonatehq:resonate-sdk-java:0.1.1, the first published release on Maven Central. Expect API changes before v1.0.

What this demonstrates

  • A multi-step durable workflow: each tick runs a step and then sleeps.
  • ctx.sleep(Duration) — a durable sleep that can suspend for seconds, hours, or days and resume exactly where it left off after a crash.
  • Crash resilience: restart the worker mid-countdown and already-sent ticks short-circuit instead of replaying.

The code

public static int countdown(Context ctx, int start, int stepSeconds) {
    int sent = 0;
    for (int i = start; i > 0; i--) {
        ctx.run(Countdown::tick, i).await();   // durable step
        sent++;
        if (i > 1) {
            ctx.sleep(Duration.ofSeconds(stepSeconds)).await(); // durable sleep
        }
    }
    return sent;
}

public static String tick(Context ctx, int count) {
    System.out.println("  [tick] " + count);
    return "ok";
}

tick is wrapped in ctx.run so its result is recorded in a durable promise. The side effect (the println) lives in the leaf, which settles once and never re-runs — so on resume after a crash, already-sent ticks are not re-printed.

Prerequisites

Setup

git clone https://github.com/resonatehq-examples/example-countdown-java.git
cd example-countdown-java

Run it

In one terminal, start the dev server:

resonate dev

In another, run the example (defaults to start=3, one second between ticks):

./gradlew run

Pass your own start + step (seconds):

./gradlew run --args="5 2"

What to look for

Expected output for the default run:

[countdown] starting workflow id=countdown-... start=3 step=1s
  [tick] 3
  [tick] 2
  [tick] 1
[countdown] done; sent 3 notifications

While a longer countdown is running (e.g. --args="5 10"), inspect the durable promises with resonate tree <id> — each tick is a resolved run promise and each gap is a sleep promise. Kill the worker mid-countdown and restart it: the countdown resumes from the pending sleep rather than starting over.

File structure

example-countdown-java/
├── src/main/java/io/resonatehq/examples/countdown/Countdown.java
├── build.gradle.kts     dependencies + Java 21 toolchain + main class
├── settings.gradle.kts  project name
├── gradlew, gradle/      Gradle wrapper
├── LICENSE              Apache-2.0
└── README.md

Next steps

Community

License

Apache-2.0

About

Durable countdown demonstrating ctx.sleep and durable steps with the Resonate Java SDK.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages