Skip to content

Resonate setup - #4794

Merged
marcoacierno merged 13 commits into
mainfrom
resonate
Oct 30, 2026
Merged

marcoacierno merged 13 commits into
mainfrom
resonate

Conversation

@marcoacierno

Copy link
Copy Markdown
Member

What

ToDo

@vercel

vercel Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
pycon Ready Ready Preview Oct 30, 2026 7:58pm UTC

@claude

claude Bot commented Aug 15, 2026 •

Copy link
Copy Markdown
Contributor

Adds Resonate durable-workflow infrastructure: a resonate_worker management command, a pycon.resonate_app helper module (get_resonate, start_workflow, database_step), settings, docker-compose services, and docs.

Issues

  • Missing test coverage: backend/pycon/tests/test_resonate_worker.py only covers the reload flag and the RESONATE_URL guard. start_workflow, database_step and _database_step_signature have no tests, though they hold most of the non-trivial logic. These are annotation resolution, the NameError fallback, and skipping connections inside an atomic block.
  • start_workflow uses asyncio.run (backend/pycon/resonate_app.py:244). It raises RuntimeError if called from a thread with a running loop, such as an async view or an async Strawberry resolver. It also builds and starts a new client on every call. The docstring should say it is sync-only, or the function should fall back to a worker thread. A test for the sync path is also needed.
  • Shutdown can hit the timeout: the atexit hook (resonate_worker.py:128-137) blocks the main thread for up to 5s waiting on stopped. If resonate.stop() raises, stopped.set() in finally still runs, so that case is fine. A task that ignores cancellation will hit the timeout and be killed.
  • Registering pycon in INSTALLED_APPS (settings/base.py) only to discover the management command is a broad change. It also makes autodiscover_modules('workflows') and other app-scanning code treat the project package as an app. Check that nothing else (for example migrations or translation discovery) is affected.
  • docker-compose.yml: resonate-ui uses a :latest tag and resonate binds CORS ['*']. Both are acceptable for local dev, but they should not be copied to a production deployment. RESONATE_URL is also injected into the backend service, so tests that rely on an empty URL need settings.RESONATE_URL set explicitly, as the new tests do.

@codecov

codecov Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 42.72727% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.17%. Comparing base (8d5f33a) to head (1433e31).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4794      +/-   ##
==========================================
- Coverage   92.70%   92.17%   -0.54%     
==========================================
  Files         356      358       +2     
  Lines       10569    10679     +110     
  Branches      902      910       +8     
==========================================
+ Hits         9798     9843      +45     
- Misses        661      725      +64     
- Partials      110      111       +1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Adds the Python side of the Resonate setup: a shared Resonate instance
workflow modules register against, autodiscovery of `<app>/workflows.py`,
a `resonate_worker` management command running the worker process, and
`start_workflow()` for triggering a workflow from synchronous Django code.

Durable functions execute on an event loop, where the Django ORM refuses
to run, so ORM-using steps are wrapped with `database_step`: it hands the
body to asgiref's thread-sensitive executor (one thread, one connection)
and recycles stale connections, skipping any connection inside an atomic
block since that one belongs to whoever opened the transaction.

The `pycon` package is registered as an app so its project-level
management commands are discoverable; it has no models.
Without `RESONATE_URL` the SDK falls back to its in-process connection,
where `start_workflow` would happily create a promise nothing ever
executes, and the worker would sit listening to itself. Both now fail
loudly instead.
Editing a workflow meant restarting the worker by hand for it to run in
its new shape. It now goes through Django's autoreloader, on by default
under DEBUG and switchable with --reload/--no-reload, the way runserver
behaves.

The reloader runs the worker in a daemon thread and exits the process
from the main thread, where the worker's own signal handlers cannot be
installed, so under it the worker stops from an exit hook instead: its
tasks are released back to the server rather than left to lapse with the
killed process.
The SDK reads RESONATE_URL (and RESONATE_HOST/SCHEME/PORT) from the
environment when it is not told a URL, which is how a test process that
happens to run with those variables set -- a container that also runs the
worker, say -- ends up talking to a real server and reusing promises
between runs. Hiding the environment from the SDK leaves Django settings
as the single source.
The wiring was assembled into a kwargs dict so two of its entries could be
left out conditionally; passing the SDK's own defaults (`url=None`,
`sources=None`) says the same thing in one call.
@marcoacierno
marcoacierno merged commit 8586c78 into main Oct 30, 2026
9 checks passed
@marcoacierno
marcoacierno deleted the resonate branch October 30, 2026 20:09

This branch was successfully deployed

1 active deployment
Preview — 1433e314 Deployed Oct 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant