From c65e5ded227f20ecf875b66f0b4913398ca9cbab Mon Sep 17 00:00:00 2001 From: PhiLily <252857470+PhiLily@users.noreply.github.com> Date: Mon, 28 Sep 2026 12:28:21 +0300 Subject: [PATCH] Release django-ox 1.7.0 Set the version to 1.7.0 and date the CHANGELOG 2026-09-28. Add upgrade guidance for worker-loop claim recovery, fork identity and stable recovery logs. No database migration is required. Recovery requires upgraded workers running Worker.run() on PostgreSQL with psycopg 3, MySQL or SQLite. run_once(), testing.run_tasks() and psycopg2 retain 1.6.0 behavior on claim errors. Document the stop-time pool budget of max_size + 3 server connections per worker process. Update SECURITY.md's supported-versions table to `1.7.x | yes`. Update docs/pro.md to state that `oxpull==1.7.0` pins `django-ox==1.7.0`. Set docs/stability.md to `django-ox~=1.7.0`. --- CHANGELOG.md | 9 ++++++++- SECURITY.md | 2 +- docs/llms-full.txt | 15 +++++++++++---- docs/pro.md | 4 ++-- docs/stability.md | 2 +- pyproject.toml | 2 +- src/django_ox/__init__.py | 2 +- 7 files changed, 25 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c40da8..1e303f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [1.7.0] - 2026-09-28 + +**Upgrading to 1.7.0:** No database migration is required. Upgrade workers to recover their own unconfirmed claims. Recovery runs only in `Worker.run()`, the loop used by `ox_worker`, on PostgreSQL with psycopg 3, MySQL and SQLite. `Worker.run_once()`, `testing.run_tasks()` and PostgreSQL with psycopg2 retain 1.6.0 behavior on claim errors. A mixed fleet with 1.5.0 and 1.6.0 workers was tested; recovery applies only to upgraded workers' own claims. + +If a claim commits but its reply is lost, the loop looks for eligible rows on later poll passes, or once at stop, and returns them to `READY` with the attempt refunded within `LOCK_TIMEOUT` and before lease expiry. Recovery is not guaranteed: worker death, prolonged outages, late commit visibility or continuous shared-Worker claims can leave rows for the reaper, consuming the attempt and becoming `LOST` on the final attempt. Stop-time recovery has backend-specific waiting limits, not a shutdown deadline. With Django's PostgreSQL pool, budget up to `max_size + 3` server connections per worker process during that look, rather than `max_size + 2`. + +A Worker inherited across a fork takes a new child id. Fork before the Worker claims anything; handing an already-claimed row to a child is unsupported. This does not make inherited connections or arbitrary native forks safe. An inherited shared heartbeat path proves only that one writer is alive. The recovery log events join the stable log contract. ### Fixed @@ -1795,6 +1801,7 @@ Initial release. the public API surface, the pre-1.0 SemVer rule, the deprecation window, and the supported Python and Django matrix. +[1.7.0]: https://github.com/oxpull/django-ox/compare/v1.6.0...v1.7.0 [1.6.0]: https://github.com/oxpull/django-ox/compare/v1.5.0...v1.6.0 [1.5.0]: https://github.com/oxpull/django-ox/compare/v1.4.0...v1.5.0 [1.4.0]: https://github.com/oxpull/django-ox/compare/v1.3.1...v1.4.0 diff --git a/SECURITY.md b/SECURITY.md index f2ffae0..7f2a0bf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -96,7 +96,7 @@ input by string formatting. | Version | Supported | | ------- | --------- | -| 1.6.x | yes | +| 1.7.x | yes | | older | no | ## Reporting a vulnerability diff --git a/docs/llms-full.txt b/docs/llms-full.txt index 0a1fdba..9741f13 100644 --- a/docs/llms-full.txt +++ b/docs/llms-full.txt @@ -6531,7 +6531,7 @@ process that shares a database before anything writes the new status. The release notes name the value, say how it reads through `django.tasks`, and give the upgrade and rollback steps. -Pin accordingly: `django-ox~=1.6.0` accepts patch releases only; +Pin accordingly: `django-ox~=1.7.0` accepts patch releases only; `django-ox~=1.3` accepts the current major line. ## Deprecation policy @@ -6697,8 +6697,8 @@ the `django-tasks` backport; Pro does not. schedule rows on a queue no backend accepts reports `oxpull.E008` instead. Workflows need Oxpull Pro 1.3.0 or later. -Each Pro release pins django-ox exactly: `oxpull==1.6.0` pins -`django-ox==1.6.0`. +Each Pro release pins django-ox exactly: `oxpull==1.7.0` pins +`django-ox==1.7.0`. Pro runs on the databases the free tier tests in CI: SQLite, PostgreSQL and MySQL 8. MariaDB 10.6+ takes the same claim path but is not @@ -7111,7 +7111,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [1.7.0] - 2026-09-28 + +**Upgrading to 1.7.0:** No database migration is required. Upgrade workers to recover their own unconfirmed claims. Recovery runs only in `Worker.run()`, the loop used by `ox_worker`, on PostgreSQL with psycopg 3, MySQL and SQLite. `Worker.run_once()`, `testing.run_tasks()` and PostgreSQL with psycopg2 retain 1.6.0 behavior on claim errors. A mixed fleet with 1.5.0 and 1.6.0 workers was tested; recovery applies only to upgraded workers' own claims. + +If a claim commits but its reply is lost, the loop looks for eligible rows on later poll passes, or once at stop, and returns them to `READY` with the attempt refunded within `LOCK_TIMEOUT` and before lease expiry. Recovery is not guaranteed: worker death, prolonged outages, late commit visibility or continuous shared-Worker claims can leave rows for the reaper, consuming the attempt and becoming `LOST` on the final attempt. Stop-time recovery has backend-specific waiting limits, not a shutdown deadline. With Django's PostgreSQL pool, budget up to `max_size + 3` server connections per worker process during that look, rather than `max_size + 2`. + +A Worker inherited across a fork takes a new child id. Fork before the Worker claims anything; handing an already-claimed row to a child is unsupported. This does not make inherited connections or arbitrary native forks safe. An inherited shared heartbeat path proves only that one writer is alive. The recovery log events join the stable log contract. ### Fixed @@ -8901,6 +8907,7 @@ Initial release. the public API surface, the pre-1.0 SemVer rule, the deprecation window, and the supported Python and Django matrix. +[1.7.0]: https://github.com/oxpull/django-ox/compare/v1.6.0...v1.7.0 [1.6.0]: https://github.com/oxpull/django-ox/compare/v1.5.0...v1.6.0 [1.5.0]: https://github.com/oxpull/django-ox/compare/v1.4.0...v1.5.0 [1.4.0]: https://github.com/oxpull/django-ox/compare/v1.3.1...v1.4.0 diff --git a/docs/pro.md b/docs/pro.md index 6165ef8..6a2f890 100644 --- a/docs/pro.md +++ b/docs/pro.md @@ -58,8 +58,8 @@ the `django-tasks` backport; Pro does not. schedule rows on a queue no backend accepts reports `oxpull.E008` instead. Workflows need Oxpull Pro 1.3.0 or later. -Each Pro release pins django-ox exactly: `oxpull==1.6.0` pins -`django-ox==1.6.0`. +Each Pro release pins django-ox exactly: `oxpull==1.7.0` pins +`django-ox==1.7.0`. Pro runs on the databases the free tier tests in CI: SQLite, PostgreSQL and MySQL 8. MariaDB 10.6+ takes the same claim path but is not diff --git a/docs/stability.md b/docs/stability.md index abd6542..adb905e 100644 --- a/docs/stability.md +++ b/docs/stability.md @@ -291,7 +291,7 @@ process that shares a database before anything writes the new status. The release notes name the value, say how it reads through `django.tasks`, and give the upgrade and rollback steps. -Pin accordingly: `django-ox~=1.6.0` accepts patch releases only; +Pin accordingly: `django-ox~=1.7.0` accepts patch releases only; `django-ox~=1.3` accepts the current major line. ## Deprecation policy diff --git a/pyproject.toml b/pyproject.toml index cd1d429..04ce56d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "django-ox" -version = "1.6.0" +version = "1.7.0" description = "Django tasks in your database, with retries and automatic recovery when a worker dies." readme = "README.md" license = "BSD-3-Clause" diff --git a/src/django_ox/__init__.py b/src/django_ox/__init__.py index 179b20c..9aa6643 100644 --- a/src/django_ox/__init__.py +++ b/src/django_ox/__init__.py @@ -6,7 +6,7 @@ from .tasks import BackoffCallback, PolicyTask __all__ = ["BackoffCallback", "PolicyTask", "__version__", "deadline", "remaining"] -__version__ = "1.6.0" +__version__ = "1.7.0" def __getattr__(name: str) -> Any: