diff --git a/CHANGELOG.md b/CHANGELOG.md index deeeea2ef..83c90c36b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ Notable changes between releases. Detailed migration notes for storage transitio ## [Unreleased] +## [0.6.13] — 2026-11-06 + +Ships everything in 0.6.13-alpha.1, which soaked without regressions, plus the batch-enqueue deadlock fix. + +### Added + +- **`QueueStorage::rescue_stale_heartbeats_with_dlq`, + `rescue_expired_deadlines_with_dlq` and `rescue_expired_callbacks_with_dlq`** + take a per-queue predicate and dead-letter exhausted attempts in the rescue + transaction. The existing methods keep their behaviour and fail exhausted + attempts into `done_entries`. + +### Changed + +- **One LISTEN connection per runtime, idle polling backoff and bounded claims.** Queue dispatchers share a listener and a runtime-wide claim semaphore (`ClientBuilder::max_concurrent_claims`). Empty queues back off from `poll_interval` to a 2 s cap when notifications are available; poll-only runtimes retain `poll_interval`. Saturated claim waits observe shutdown, and late-starting tasks receive cancellation. Dispatcher exit and worker drain share the timeout. The idle cap stays internal to preserve `QueueConfig` struct literals. + ### Fixed - **Batch enqueues take their lane locks in one order, so they no longer @@ -23,22 +39,6 @@ Notable changes between releases. Detailed migration notes for storage transitio statement order; see "`deadlock detected` while enqueueing" in the troubleshooting guide. -## [0.6.13-alpha.1] — 2026-11-05 - -### Added - -- **`QueueStorage::rescue_stale_heartbeats_with_dlq`, - `rescue_expired_deadlines_with_dlq` and `rescue_expired_callbacks_with_dlq`** - take a per-queue predicate and dead-letter exhausted attempts in the rescue - transaction. The existing methods keep their behaviour and fail exhausted - attempts into `done_entries`. - -### Changed - -- **One LISTEN connection per runtime, idle polling backoff and bounded claims.** Queue dispatchers share a listener and a runtime-wide claim semaphore (`ClientBuilder::max_concurrent_claims`). Empty queues back off from `poll_interval` to a 2 s cap when notifications are available; poll-only runtimes retain `poll_interval`. Saturated claim waits observe shutdown, and late-starting tasks receive cancellation. Dispatcher exit and worker drain share the timeout. The idle cap stays internal to preserve `QueueConfig` struct literals. - -### Fixed - - **Scheduled, snoozed and retry-after jobs are no longer held back while the maintenance leader is overloaded.** The leader backs a maintenance branch off for a cooldown after its body repeatedly runs longer than its diff --git a/Cargo.lock b/Cargo.lock index 42187124f..30bd194c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,7 +383,7 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "awa" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "async-trait", "awa-macros", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "awa-cli" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "assert_cmd", "awa-model", @@ -430,7 +430,7 @@ dependencies = [ [[package]] name = "awa-macros" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -440,7 +440,7 @@ dependencies = [ [[package]] name = "awa-metrics" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "awa-model", "opentelemetry", @@ -449,7 +449,7 @@ dependencies = [ [[package]] name = "awa-model" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "awa-macros", "blake3", @@ -470,7 +470,7 @@ dependencies = [ [[package]] name = "awa-seaorm" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "awa", "awa-testing", @@ -483,7 +483,7 @@ dependencies = [ [[package]] name = "awa-testing" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "async-trait", "awa-model", @@ -498,7 +498,7 @@ dependencies = [ [[package]] name = "awa-ui" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "awa-metrics", "awa-model", @@ -521,7 +521,7 @@ dependencies = [ [[package]] name = "awa-worker" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index e47277ca0..eba7da12b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ exclude = ["awa-python", "spike"] [workspace.package] -version = "0.6.13-alpha.1" +version = "0.6.13" edition = "2021" license = "MIT OR Apache-2.0" description = "Postgres-native background job queue — transactional enqueue, heartbeat crash recovery, SKIP LOCKED dispatch" @@ -25,11 +25,11 @@ categories = ["database", "asynchronous", "web-programming"] [workspace.dependencies] # Internal crates -awa-model = { path = "awa-model", version = "0.6.13-alpha.1" } -awa-macros = { path = "awa-macros", version = "0.6.13-alpha.1" } -awa-metrics = { path = "awa-metrics", version = "0.6.13-alpha.1" } -awa-worker = { path = "awa-worker", version = "0.6.13-alpha.1" } -awa = { path = "awa", version = "0.6.13-alpha.1" } +awa-model = { path = "awa-model", version = "0.6.13" } +awa-macros = { path = "awa-macros", version = "0.6.13" } +awa-metrics = { path = "awa-metrics", version = "0.6.13" } +awa-worker = { path = "awa-worker", version = "0.6.13" } +awa = { path = "awa", version = "0.6.13" } # Database sea-orm = { version = "=2.0.0-rc.38", default-features = false, features = ["sqlx-postgres", "runtime-tokio-rustls", "with-chrono", "with-json"] } diff --git a/awa-cli/Cargo.toml b/awa-cli/Cargo.toml index 33c8616f2..14f235f7b 100644 --- a/awa-cli/Cargo.toml +++ b/awa-cli/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" [dependencies] awa-model.workspace = true awa-worker.workspace = true -awa-ui = { path = "../awa-ui", version = "0.6.13-alpha.1" } +awa-ui = { path = "../awa-ui", version = "0.6.13" } axum.workspace = true sqlx.workspace = true tokio.workspace = true @@ -28,5 +28,5 @@ hex.workspace = true uuid.workspace = true [dev-dependencies] -awa-testing = { path = "../awa-testing", version = "0.6.13-alpha.1" } +awa-testing = { path = "../awa-testing", version = "0.6.13" } assert_cmd = "2" diff --git a/awa-cli/pyproject.toml b/awa-cli/pyproject.toml index a64e8b7fd..7e4f95bbf 100644 --- a/awa-cli/pyproject.toml +++ b/awa-cli/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "awa-cli" -version = "0.6.13-alpha.1" +version = "0.6.13" description = "CLI for the Awa Postgres-native job queue (migrations, admin, serve)" readme = "README.md" requires-python = ">=3.10" diff --git a/awa-python/Cargo.lock b/awa-python/Cargo.lock index 7767fe6b5..fa27a3b79 100644 --- a/awa-python/Cargo.lock +++ b/awa-python/Cargo.lock @@ -95,7 +95,7 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "awa-macros" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -105,7 +105,7 @@ dependencies = [ [[package]] name = "awa-metrics" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "awa-model", "opentelemetry", @@ -113,7 +113,7 @@ dependencies = [ [[package]] name = "awa-model" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "awa-macros", "blake3", @@ -133,7 +133,7 @@ dependencies = [ [[package]] name = "awa-python" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "async-trait", "awa-model", @@ -156,7 +156,7 @@ dependencies = [ [[package]] name = "awa-worker" -version = "0.6.13-alpha.1" +version = "0.6.13" dependencies = [ "async-trait", "awa-macros", diff --git a/awa-python/Cargo.toml b/awa-python/Cargo.toml index 181d8f3c2..373a48e8e 100644 --- a/awa-python/Cargo.toml +++ b/awa-python/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awa-python" -version = "0.6.13-alpha.1" +version = "0.6.13" edition = "2021" [lib] @@ -12,8 +12,8 @@ default = ["cel"] cel = ["awa-model/cel"] [dependencies] -awa-model = { path = "../awa-model", version = "0.6.13-alpha.1" } -awa-worker = { path = "../awa-worker", version = "0.6.13-alpha.1", features = ["__python-bridge"] } +awa-model = { path = "../awa-model", version = "0.6.13" } +awa-worker = { path = "../awa-worker", version = "0.6.13", features = ["__python-bridge"] } pyo3 = { version = "0.29", features = ["macros", "abi3-py310", "chrono"] } pyo3-async-runtimes = { version = "0.29", features = ["tokio-runtime"] } sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres", "chrono", "json"] } diff --git a/awa-python/pyproject.toml b/awa-python/pyproject.toml index a9872c7f8..b20fdc21d 100644 --- a/awa-python/pyproject.toml +++ b/awa-python/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "maturin" [project] name = "awa-pg" requires-python = ">=3.10" -version = "0.6.13-alpha.1" +version = "0.6.13" description = "Postgres-native background job queue — Python SDK with async/sync workers, transactional enqueue, and progress tracking. Install awa-pg[ui] to add the bundled web dashboard." readme = "README.md" license = {text = "MIT OR Apache-2.0"} @@ -32,7 +32,7 @@ classifiers = [ # # Kept opt-in so the default `awa-pg` install stays small — workers and # producers don't need the ~10 MB UI bundle. -ui = ["awa-cli==0.6.13-alpha.1"] +ui = ["awa-cli==0.6.13"] [project.urls] Homepage = "https://github.com/hardbyte/awa" diff --git a/awa-python/uv.lock b/awa-python/uv.lock index 7378a6aea..8b3cbff7a 100644 --- a/awa-python/uv.lock +++ b/awa-python/uv.lock @@ -88,12 +88,12 @@ wheels = [ [[package]] name = "awa-cli" -version = "0.6.13a1" +version = "0.6.13" source = { directory = "../awa-cli" } [[package]] name = "awa-pg" -version = "0.6.13a1" +version = "0.6.13" source = { editable = "." } [package.optional-dependencies] diff --git a/awa-seaorm/Cargo.toml b/awa-seaorm/Cargo.toml index 208dfad3d..781c95ab9 100644 --- a/awa-seaorm/Cargo.toml +++ b/awa-seaorm/Cargo.toml @@ -14,6 +14,6 @@ serde_json.workspace = true sqlx.workspace = true [dev-dependencies] -awa-testing = { path = "../awa-testing", version = "0.6.13-alpha.1" } +awa-testing = { path = "../awa-testing", version = "0.6.13" } serde = { workspace = true, features = ["derive"] } tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/awa/Cargo.toml b/awa/Cargo.toml index 4f0ae480d..437cb057b 100644 --- a/awa/Cargo.toml +++ b/awa/Cargo.toml @@ -20,7 +20,7 @@ awa-macros.workspace = true awa-worker.workspace = true [dev-dependencies] -awa-testing = { path = "../awa-testing", version = "0.6.13-alpha.1" } +awa-testing = { path = "../awa-testing", version = "0.6.13" } sqlx.workspace = true serde.workspace = true serde_json.workspace = true