Skip to content

v0.26.0 - Major Release (UX and polish focused) - #58

Open
TkTech wants to merge 51 commits into
mainfrom
26_ux
Open

TkTech wants to merge 51 commits into
mainfrom
26_ux

Conversation

@TkTech

@TkTech TkTech commented Oct 28, 2025

Copy link
Copy Markdown
Owner

(This is a huge release, changelog to come. WIP)

0.26.0

✨ Improvements

  • Reworked the dashboard, much more informative for operational insights, light/dark themes.
  • Added much, much better composable filtering widgets to both jobs and workflows.
  • Added a visualization of your upcoming (and past) cron schedule, making it easy to identify overloaded periods.
  • Added a realtime view of the internal Chancy communication traffic, helping to debug and identify pain points (like using push() in a loop instead of a single push_many())
  • HTTP API now supports mutation - create queues on the fly, move jobs around, retry workflows, etc...
  • HTTP API is now stable, with documentation still a work in progress.
  • HTTP API now includes an unauthenticated endpoint for health checks, meant for docker/containers (Best way to do containerised healthchecks on workers #54)
  • Added dozens of new metrics, including metrics for the metrics plugin and metrics on workflows.
  • Added postgres 18 to test matrix (@jklaise)
  • The starlette app can now be created without being started for advanced use cases, and the mounting prefix for the SPA can be changed (@jklaise, Feature request: Expose Starlette API app so it can be mounted onto an existing FastAPI/ASGI app #64)
  • Workflow performance has been significantly improved and can now handle many, individual workflows with thousands of jobs without issue.
  • Workflows will now be validated before saving, verifying there are no unreachable nodes in the DAG, no cycles, etc
  • Can now be used as a django-tasks backend, albeit with less functionality than using Chancy directly

🐛 Fixes

image image image image image

@codecov

codecov Bot commented Oct 28, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.35890% with 543 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.86%. Comparing base (0cb14b1) to head (28867f1).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
chancy/plugins/api/core.py 0.00% 215 Missing ⚠️
chancy/contrib/django/backend.py 0.00% 70 Missing ⚠️
chancy/plugins/api/auth.py 0.00% 57 Missing ⚠️
chancy/worker.py 80.51% 45 Missing ⚠️
chancy/contrib/django/task_wrapper.py 0.00% 24 Missing ⚠️
chancy/executors/process.py 67.74% 20 Missing ⚠️
chancy/plugins/debug.py 0.00% 19 Missing ⚠️
chancy/plugins/workflow/api.py 0.00% 18 Missing ⚠️
chancy/cli/worker.py 0.00% 11 Missing ⚠️
chancy/app.py 89.89% 10 Missing ⚠️
... and 19 more

❗ There is a different number of reports uploaded between BASE (0cb14b1) and HEAD (28867f1). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (0cb14b1) HEAD (28867f1)
unittests 11 10
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #58      +/-   ##
==========================================
- Coverage   73.19%   67.86%   -5.33%     
==========================================
  Files          58       62       +4     
  Lines        3193     3772     +579     
==========================================
+ Hits         2337     2560     +223     
- Misses        856     1212     +356     
Flag Coverage Δ
unittests 67.86% <58.35%> (-5.33%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 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.

@TkTech TkTech changed the title v0.26.0 - Major Release v0.26.0 - Major Release (UX and polish focused) Oct 29, 2025
@TkTech

TkTech commented Nov 29, 2025

Copy link
Copy Markdown
Owner Author

Added a cron job visualizer.

image

API plugin settings (host, port, debug, allow_origin) are now overridden if the corresponding CLI flags are explicitly provided, even when an Api instance is defined outside the default behaviour.
@fcortes

fcortes commented Dec 17, 2025

Copy link
Copy Markdown

Hi! I saw that you mentioned django-tasks compatibility on this PR but couldn't find any reference about it on the code. Do you mind committing those changes or maybe open a new PR with it (to avoid getting this one so large). I was playing around with chancy and also have a semi-functional implementation and it would be nice to see how you managed some issues I've been encountering.

Great project btw!

Respect CLI flags for API plugin configuration
@phillycheeze

Copy link
Copy Markdown

@TkTech We just started leveraging chancy and super excited for this new dashboard! Any outstanding items you're looking for help with?

@TkTech

TkTech commented Jan 28, 2026

Copy link
Copy Markdown
Owner Author

@TkTech We just started leveraging chancy and super excited for this new dashboard! Any outstanding items you're looking for help with?

It's been running for testing in a production environment since Monday, so I'd say we'll release this weekend if all goes well.

@TkTech

TkTech commented Jan 29, 2026

Copy link
Copy Markdown
Owner Author

Hi! I saw that you mentioned django-tasks compatibility on this PR but couldn't find any reference about it on the code. Do you mind committing those changes or maybe open a new PR with it (to avoid getting this one so large). I was playing around with chancy and also have a semi-functional implementation and it would be nice to see how you managed some issues I've been encountering.

Great project btw!

I've left some comments in the #82 ticket regarding this, there are some behavioral Qs to answer before we commit to anything.

luca-montaigut and others added 3 commits September 10, 2026 15:40
Pushing jobs whose unique keys already exist takes row locks through the
ON CONFLICT ... DO UPDATE clause, and the worker's batched job updates
take row locks too. When the two transactions overlapped and locked the
same rows in a different order, Postgres killed one of them with
DeadlockDetected, failing the push or the update batch.

Both code paths now sort by the same key before touching rows: pushes
insert in unique_key order (returning references in the caller's order),
and the worker sorts its pending updates by (unique_key, id). A
regression test replays the interleaving deterministically.

Co-authored-by: audecasteigts <aude.casteigts@gmail.com>
…#46)

Custom executors need a supported way to inject their own keyword
arguments (database pools, clients, ...) into every job they run. The
built-in executors resolved the function through a private static helper
that ignored subclass overrides, so the public get_function_and_kwargs
was never consulted.

get_function_and_kwargs is now a classmethod holding the resolution
logic, and prepare_job_for_execution goes through it for every executor.
The job-context detection used by co-operative time limits now checks
the resolved kwargs for the job instance instead of a side channel, so
overrides cannot break it.

Because job_wrapper and prepare_job_for_execution are classmethods, the
override runs on the side that executes the job (event loop, pool
thread, sub-interpreter or child process); nothing crosses that boundary
beyond the executor's importable name. The docstring spells this out and
an end-to-end test checks the injection on every built-in executor.

Co-authored-by: PaulM5406 <ppsmilesi@protonmail.com>
@luca-montaigut

Copy link
Copy Markdown

Hi @TkTech, I'm a colleague of @AudeCstg and @PaulM5406 at Ouihelp. We run Chancy in production (8 queues, ~60 job types, ~50 cron schedules) on a patched 0.25.0 and would very much like to be back on a stock release. Concretely:

  1. Acquire job row locks in a consistent order to prevent deadlocks (#89) #90 (deadlock between pushes with unique keys and the worker's update batch, Possible conflict between Chancy._push_job_sql and Worker._maintain_updates #89) is rebased on 26_ux, reduced to the lock ordering that 26_ux doesn't already cover, with a deterministic regression test.
  2. Make Executor.get_function_and_kwargs the overridable resolution hook. #46 (get_function_and_kwargs overridable in executor subclasses) is retargeted to 26_ux and adapted to prepare_job_for_execution.
  3. The CI on this PR is red only because Django 6 refuses PostgreSQL 14: two Django tests error on the PG14 jobs, and fail-fast then cancels the PG18 jobs that otherwise pass (128 passed). This makes the PG14 jobs skip the Django tests, the dedicated Django 6 job still covers them on PG18:
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -103,11 +103,15 @@
       - name: Installing dependencies (Python)
         run: uv sync --all-extras
 
+      # Django 6 (the version resolved by `uv sync --all-extras`) refuses to
+      # connect to PostgreSQL < 15, so the Django tests only run on the newer
+      # PostgreSQL of the matrix. Chancy itself still supports 14.
       - name: Running tests (parallel)
         run: |
-          uv run pytest -n auto -v --cov=chancy --cov-report=xml
+          uv run pytest -n auto -v --cov=chancy --cov-report=xml ${{ matrix.pg == '14' && '--ignore=tests/contrib/django' || '' }}
 
       - name: Running Django ORM tests (sequential)
+        if: matrix.pg != '14'
         run: |
           uv run pytest tests/contrib/django/test_models.py -v --cov=chancy --cov-report=xml --cov-append

If it helps get 0.26 out, we're happy to take on some of the open issues you'd want in the release. Let us know what would be most useful.

@TkTech

TkTech commented Sep 15, 2026

Copy link
Copy Markdown
Owner Author

Heya @luca-montaigut. Unfortunately I was caught in a layoff, and so the various OSS projects had to take a back seat for a bit. I'll take a look at #90 and #46. For the test failures, rather than just ignoring 14 we'd rather expand the matrix to also specify the supported postgres version range, since both those django versions and PG14 are still supported (until November 12, 2026, at which time it'll be dropped).

Thanks for your patience! Unfortunately v0.26 took far too long to ship.

Shutdown is now repeatable and re-entrant.
Write updates in the outbox in order, so newer runs that rapidly ran
after a cancel or failuer cannot be overwritten.
Executor cleanup no longer blocks the event loop.
Added a public `Worker.flush()` to explicitly drain the queue.
…-subclass' of github.com:PaulM5406/chancy into PaulM5406-enabling-overriding-get_function_and_kwargs-in-executor-subclass
@TkTech

TkTech commented Sep 16, 2026

Copy link
Copy Markdown
Owner Author

The sporadic test hangs on 3.11 seem to be this upstream bug in CPython python/cpython#86296.

  Worker._maintain_queues()
    Chancy.get_all_queues() 
      AsyncCursor.execute() 
        AsyncConnection.wait()
          wait_async()
            await wait_for(ev.wait(), interval) # <-- this guy

Specifically, deep down inside of psycopg it's using wait_for(). If ev.wait() finishes at the same time as a cancellation was supposed to be raised, then the cancellation gets consumed and never re-raised. So our shutting down Worker tries to cleanup properly with TaskManager.cancel("queues") and gets stuck forever.

@PaulM5406

Copy link
Copy Markdown
Contributor

The sporadic test hangs on 3.11 seem to be this upstream bug in CPython python/cpython#86296.

  Worker._maintain_queues()
    Chancy.get_all_queues() 
      AsyncCursor.execute() 
        AsyncConnection.wait()
          wait_async()
            await wait_for(ev.wait(), interval) # <-- this guy

Specifically, deep down inside of psycopg it's using wait_for(). If ev.wait() finishes at the same time as a cancellation was supposed to be raised, then the cancellation gets consumed and never re-raised. So our shutting down Worker tries to cleanup properly with TaskManager.cancel("queues") and gets stuck forever.

Hey @TkTech,
I have opened http://github.com/TkTech/chancy/pull/97 to manage this issue in Chancy.

@TkTech

TkTech commented Sep 19, 2026

Copy link
Copy Markdown
Owner Author

The sporadic test hangs on 3.11 seem to be this upstream bug in CPython python/cpython#86296.

  Worker._maintain_queues()
    Chancy.get_all_queues() 
      AsyncCursor.execute() 
        AsyncConnection.wait()
          wait_async()
            await wait_for(ev.wait(), interval) # <-- this guy

Specifically, deep down inside of psycopg it's using wait_for(). If ev.wait() finishes at the same time as a cancellation was supposed to be raised, then the cancellation gets consumed and never re-raised. So our shutting down Worker tries to cleanup properly with TaskManager.cancel("queues") and gets stuck forever.

Hey @TkTech, I have opened http://github.com/TkTech/chancy/pull/97 to manage this issue in Chancy.

Thanks @PaulM5406! An upstream psycopg release fixes this in 3.3.6 which was put out yesterday. I believe with uv I can do CPython version-specific pinning, so we can fix this by just requiring >=3.3.6 on 3.11.

This branch has not been deployed

No deployments
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.

7 participants