diff --git a/CHANGELOG.md b/CHANGELOG.md index 18312673..2e6715c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,59 @@ All notable changes to taskito are documented here. The format is based on [Semantic Versioning](https://semver.org/spec/v2.0.0.html). All SDKs (Python, Node, Java) and the underlying Rust crates are released together, in lock-step. +## 0.19.0 + +Parity release: the Java SDK reaches feature parity with the other SDKs (and its baseline moves +to Java 17), payload codecs land as a cross-SDK wire contract, and the resource system gains a +bounded pooled scope plus health-check-driven recreation. One breaking change in the Node SDK: +scan-heavy queue methods now return Promises. + +### Added + +- **Java SDK full parity.** Workflows grow gates, conditional steps, sub-workflows, sagas, + incremental caching, analysis/visualization, and canvas shortcuts. New: worker resource + dependency injection with five scopes (worker / thread / task / request / pooled), enqueue + predicates and interception, two-sided payload codecs with per-task annotations, signed + resource proxies with expiry/purpose binding and sessions, producer-side batching, in-process + autoscaling plus a scaler HTTP endpoint, an optional MessagePack serializer, observability + middleware, a Spring Boot 3 starter, a mesh scheduling worker, and a Panama FFM fast-path for + hot byte operations. Maven Central publishing is automated end to end. +- **Payload codecs (all SDKs).** A codec chain (gzip, AES-GCM, HMAC) that wraps the queue + serializer on both the enqueue and result paths — configurable globally or per task via a + named registry. The wire format is a cross-SDK contract: payloads encoded by one SDK decode + in any other. Dedup keys hash pre-codec bytes, so encryption does not break idempotency. +- **Pooled resource scope (Node + Java).** A bounded checkout/return pool per resource: + each task checks out one instance for its duration and returns it at task end. Capacity, + prewarm, acquire timeout, and max lifetime are configurable; instances are disposed at + worker shutdown or lifetime expiry. +- **Node resource health checks.** Per-resource `healthCheck` with automatic recreation and a + terminal unhealthy state after the recreation budget is spent. The worker heartbeat now + carries per-resource health, surfaced through `listWorkers()`. +- **Node proxy system.** Signed proxy references with a file handler (HMAC-SHA256 over a + canonical JSON form, path allowlists, TTL and purpose binding), plus proxy sessions with + identity dedup on deconstruct, signature-keyed memoization on reconstruct (re-verified on + every resolve), and LIFO cleanup on close. +- **Node enqueue interceptors.** Pass / convert / redirect / reject rules that run before + defaults, middleware, and serialization — same model as the other SDKs. +- **Java THREAD and REQUEST resource scopes**, completing the scope matrix alongside worker, + task, and pooled. + +### Changed + +- **Node (breaking): scan-heavy queue methods are now async.** `stats*`, `listJobs`, + `deadLetters*`, `purge*`, `listWorkers`, `getMetrics`, and `getJobErrors` return Promises and + no longer block the event loop; webhook `Delivery` was reshaped to the dashboard contract. +- **Java baseline is now 17** (previously 11). + +### Fixed + +- **Python results always use the queue serializer.** Task results were serialized with raw + cloudpickle on three of the four write paths while reads went through the configured + serializer; all result writes now route through the queue serializer (with a legacy fallback + so old results stay readable). +- **Node workflow tracker correctness** (static-successor cascade on managed runs, fan-out + sibling successors — both also fixed in Python), plus cursor-based task-log streaming. + ## 0.18.0 Reliability and storage release: Postgres dequeues with `SKIP LOCKED`, crashed workers' diff --git a/Cargo.lock b/Cargo.lock index e83e77d2..60723479 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1481,7 +1481,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "taskito-core" -version = "0.18.0" +version = "0.19.0" dependencies = [ "async-trait", "chrono", @@ -1505,7 +1505,7 @@ dependencies = [ [[package]] name = "taskito-java" -version = "0.18.0" +version = "0.19.0" dependencies = [ "async-trait", "crossbeam-channel", @@ -1524,7 +1524,7 @@ dependencies = [ [[package]] name = "taskito-mesh" -version = "0.18.0" +version = "0.19.0" dependencies = [ "base64", "bincode", @@ -1539,7 +1539,7 @@ dependencies = [ [[package]] name = "taskito-node" -version = "0.18.0" +version = "0.19.0" dependencies = [ "async-trait", "crossbeam-channel", @@ -1558,7 +1558,7 @@ dependencies = [ [[package]] name = "taskito-python" -version = "0.18.0" +version = "0.19.0" dependencies = [ "async-trait", "base64", @@ -1578,7 +1578,7 @@ dependencies = [ [[package]] name = "taskito-workflows" -version = "0.18.0" +version = "0.19.0" dependencies = [ "dagron-core", "diesel", diff --git a/crates/taskito-core/Cargo.toml b/crates/taskito-core/Cargo.toml index c281728a..434ea4ac 100644 --- a/crates/taskito-core/Cargo.toml +++ b/crates/taskito-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "taskito-core" -version = "0.18.0" +version = "0.19.0" edition = "2021" [features] diff --git a/crates/taskito-java/Cargo.toml b/crates/taskito-java/Cargo.toml index 2e15b9a6..2063abba 100644 --- a/crates/taskito-java/Cargo.toml +++ b/crates/taskito-java/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "taskito-java" -version = "0.18.0" +version = "0.19.0" edition = "2021" description = "Java (JNI) bindings for the Taskito task-queue core" license = "MIT" diff --git a/crates/taskito-mesh/Cargo.toml b/crates/taskito-mesh/Cargo.toml index 840a6da8..469e63a2 100644 --- a/crates/taskito-mesh/Cargo.toml +++ b/crates/taskito-mesh/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "taskito-mesh" -version = "0.18.0" +version = "0.19.0" edition = "2021" [dependencies] diff --git a/crates/taskito-node/Cargo.toml b/crates/taskito-node/Cargo.toml index fc2b155f..bae54810 100644 --- a/crates/taskito-node/Cargo.toml +++ b/crates/taskito-node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "taskito-node" -version = "0.18.0" +version = "0.19.0" edition = "2021" description = "Node.js (napi-rs) bindings for the Taskito task-queue core" license = "MIT" diff --git a/crates/taskito-python/Cargo.toml b/crates/taskito-python/Cargo.toml index f2f127e5..03983c64 100644 --- a/crates/taskito-python/Cargo.toml +++ b/crates/taskito-python/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "taskito-python" -version = "0.18.0" +version = "0.19.0" edition = "2021" [features] diff --git a/crates/taskito-workflows/Cargo.toml b/crates/taskito-workflows/Cargo.toml index 745def2d..adfa1770 100644 --- a/crates/taskito-workflows/Cargo.toml +++ b/crates/taskito-workflows/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "taskito-workflows" -version = "0.18.0" +version = "0.19.0" edition = "2021" [features] diff --git a/docs/app/lib/version.ts b/docs/app/lib/version.ts index 8425a83c..ad411799 100644 --- a/docs/app/lib/version.ts +++ b/docs/app/lib/version.ts @@ -1,2 +1,2 @@ // AUTO-GENERATED from /CHANGELOG.md by scripts/sync-changelog.mjs — do not edit directly. -export const VERSION = "0.18.0"; +export const VERSION = "0.19.0"; diff --git a/docs/content/docs/resources/changelog.mdx b/docs/content/docs/resources/changelog.mdx index 76d244a9..0e24ba93 100644 --- a/docs/content/docs/resources/changelog.mdx +++ b/docs/content/docs/resources/changelog.mdx @@ -10,6 +10,59 @@ All notable changes to taskito are documented here. The format is based on [Semantic Versioning](https://semver.org/spec/v2.0.0.html). All SDKs (Python, Node, Java) and the underlying Rust crates are released together, in lock-step. +## 0.19.0 + +Parity release: the Java SDK reaches feature parity with the other SDKs (and its baseline moves +to Java 17), payload codecs land as a cross-SDK wire contract, and the resource system gains a +bounded pooled scope plus health-check-driven recreation. One breaking change in the Node SDK: +scan-heavy queue methods now return Promises. + +### Added + +- **Java SDK full parity.** Workflows grow gates, conditional steps, sub-workflows, sagas, + incremental caching, analysis/visualization, and canvas shortcuts. New: worker resource + dependency injection with five scopes (worker / thread / task / request / pooled), enqueue + predicates and interception, two-sided payload codecs with per-task annotations, signed + resource proxies with expiry/purpose binding and sessions, producer-side batching, in-process + autoscaling plus a scaler HTTP endpoint, an optional MessagePack serializer, observability + middleware, a Spring Boot 3 starter, a mesh scheduling worker, and a Panama FFM fast-path for + hot byte operations. Maven Central publishing is automated end to end. +- **Payload codecs (all SDKs).** A codec chain (gzip, AES-GCM, HMAC) that wraps the queue + serializer on both the enqueue and result paths — configurable globally or per task via a + named registry. The wire format is a cross-SDK contract: payloads encoded by one SDK decode + in any other. Dedup keys hash pre-codec bytes, so encryption does not break idempotency. +- **Pooled resource scope (Node + Java).** A bounded checkout/return pool per resource: + each task checks out one instance for its duration and returns it at task end. Capacity, + prewarm, acquire timeout, and max lifetime are configurable; instances are disposed at + worker shutdown or lifetime expiry. +- **Node resource health checks.** Per-resource `healthCheck` with automatic recreation and a + terminal unhealthy state after the recreation budget is spent. The worker heartbeat now + carries per-resource health, surfaced through `listWorkers()`. +- **Node proxy system.** Signed proxy references with a file handler (HMAC-SHA256 over a + canonical JSON form, path allowlists, TTL and purpose binding), plus proxy sessions with + identity dedup on deconstruct, signature-keyed memoization on reconstruct (re-verified on + every resolve), and LIFO cleanup on close. +- **Node enqueue interceptors.** Pass / convert / redirect / reject rules that run before + defaults, middleware, and serialization — same model as the other SDKs. +- **Java THREAD and REQUEST resource scopes**, completing the scope matrix alongside worker, + task, and pooled. + +### Changed + +- **Node (breaking): scan-heavy queue methods are now async.** `stats*`, `listJobs`, + `deadLetters*`, `purge*`, `listWorkers`, `getMetrics`, and `getJobErrors` return Promises and + no longer block the event loop; webhook `Delivery` was reshaped to the dashboard contract. +- **Java baseline is now 17** (previously 11). + +### Fixed + +- **Python results always use the queue serializer.** Task results were serialized with raw + cloudpickle on three of the four write paths while reads went through the configured + serializer; all result writes now route through the queue serializer (with a legacy fallback + so old results stay readable). +- **Node workflow tracker correctness** (static-successor cascade on managed runs, fan-out + sibling successors — both also fixed in Python), plus cursor-based task-log streaming. + ## 0.18.0 Reliability and storage release: Postgres dequeues with `SKIP LOCKED`, crashed workers' diff --git a/sdks/java/build.gradle.kts b/sdks/java/build.gradle.kts index 02992fdb..6d5d418f 100644 --- a/sdks/java/build.gradle.kts +++ b/sdks/java/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } group = "org.byteveda" -version = "0.18.0" +version = "0.19.0" java { // Sources + javadoc jars are added by the maven-publish plugin below. diff --git a/sdks/java/graalvm-smoke/build.gradle.kts b/sdks/java/graalvm-smoke/build.gradle.kts index b9187843..e0f613c7 100644 --- a/sdks/java/graalvm-smoke/build.gradle.kts +++ b/sdks/java/graalvm-smoke/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "org.byteveda" -version = "0.18.0" +version = "0.19.0" repositories { mavenCentral() diff --git a/sdks/java/processor/build.gradle.kts b/sdks/java/processor/build.gradle.kts index c1bbb822..e21b2cb7 100644 --- a/sdks/java/processor/build.gradle.kts +++ b/sdks/java/processor/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "org.byteveda" -version = "0.18.0" +version = "0.19.0" mavenPublishing { publishToMavenCentral() diff --git a/sdks/java/test-support/build.gradle.kts b/sdks/java/test-support/build.gradle.kts index 3f175f43..5de72fa8 100644 --- a/sdks/java/test-support/build.gradle.kts +++ b/sdks/java/test-support/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "org.byteveda" -version = "0.18.0" +version = "0.19.0" mavenPublishing { publishToMavenCentral() diff --git a/sdks/node/package.json b/sdks/node/package.json index 61908f07..9ea169ec 100644 --- a/sdks/node/package.json +++ b/sdks/node/package.json @@ -1,6 +1,6 @@ { "name": "@byteveda/taskito", - "version": "0.18.0", + "version": "0.19.0", "description": "Rust-powered task queue for Node.js — no broker required.", "license": "MIT", "type": "module", diff --git a/sdks/python/pyproject.toml b/sdks/python/pyproject.toml index 74cf27ed..59482f81 100644 --- a/sdks/python/pyproject.toml +++ b/sdks/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "taskito" -version = "0.18.0" +version = "0.19.0" description = "Rust-powered task queue for Python. No broker required." requires-python = ">=3.10" license = { file = "LICENSE" } diff --git a/sdks/python/taskito/__init__.py b/sdks/python/taskito/__init__.py index cd77151e..88e1f002 100644 --- a/sdks/python/taskito/__init__.py +++ b/sdks/python/taskito/__init__.py @@ -136,4 +136,4 @@ __version__ = _get_version("taskito") except PackageNotFoundError: - __version__ = "0.18.0" + __version__ = "0.19.0"