Skip to content
Pyrula
Pre-release: the packages are not on PyPI yet, so pip install does not resolve. Build from source to try it today.

Crash and resume

A two-step workflow kills its own process between the steps; the rerun picks up the same run.

This page uses Python 3.11 to 3.15 and a POSIX shell, in the directory pyrula init wrote crash_resume.py into (quickstart). Nothing else needs to run: the run lives in .pyrula/dev.db, which outlives the process.

Export the key from Setup, or skip this to run locally.

Terminal window
export PYRULA_CLOUD_API_KEY="<key>"
Terminal window
python crash_resume.py
python crash_resume.py

The first pass runs step one, then kills its own process:

step one: RAN (this line should appear exactly once, ever)
killing this process now - run the script again

The second pass waits about five seconds for the dead process’s lock to lapse, replays step one from the journal and runs step two:

step two: RAN
result: {'first': 'one', 'second': 'two'}

step one: RAN appears once across both passes. The first pass writes the run id to .crash_resume_run so the second finds the same run; the file is deleted on completion.

With a key set, both processes report under one run id. In Runs, the run crash_resume shows step one recorded once, then the resumed attempt’s step two. Cloud draws no marker where the first process died.

To use a production-style store, start Valkey and point the script at it before the two runs:

Terminal window
docker run -d -p 6379:6379 valkey/valkey:9.1.3
export PYRULA_STORE_URL=valkey://localhost:6379

Stop it afterwards with docker stop. Run Valkey with maxmemory-policy noeviction; pyrula dev --check --store ... warns otherwise.

A step recorded before the process died is not run again. An external effect is not exactly-once: if it succeeded at the provider but the process died before the result was recorded, the step runs again. Give the provider an idempotency key derived from the work.

If something misbehaves, see Troubleshooting.

View this page as Markdown