From 2855043121589f84fa4cf54952d956406e4d1dd3 Mon Sep 17 00:00:00 2001 From: Richard McDaniel <1130888+rmcdaniel@users.noreply.github.com> Date: Fri, 13 Nov 2026 02:40:46 +0000 Subject: [PATCH] Select Workflow 2.28.0: select() losers are settled when the run closes - Concurrency: new 'Losers when the run closes' section (workflow issue 1117): a loser still open at complete/fail/continue-as-new is cancelled in the closing transaction (cancellation_reason run_closed), nothing follows the terminal event, await a loser whose effect you need; service-mode abandon keeps running without its outcome being recorded. - Continue-as-new: one paragraph pointing to it. - Compatibility: 2.28 notes (behavior change, no migration), upgrade contract link at 2.28.0; stable-releases selects 2.28.0. All seven translations and source hashes updated. Co-Authored-By: Claude Opus 5.5 --- docs/compatibility.md | 10 ++++++++-- docs/features/concurrency.md | 6 ++++++ docs/features/continue-as-new.md | 2 ++ .../current/compatibility.md | 10 ++++++++-- .../current/features/concurrency.md | 6 ++++++ .../current/features/continue-as-new.md | 2 ++ i18n/de/source-hashes.json | 6 +++--- .../current/compatibility.md | 10 ++++++++-- .../current/features/concurrency.md | 6 ++++++ .../current/features/continue-as-new.md | 2 ++ i18n/es/source-hashes.json | 6 +++--- .../current/compatibility.md | 10 ++++++++-- .../current/features/concurrency.md | 6 ++++++ .../current/features/continue-as-new.md | 2 ++ i18n/fr/source-hashes.json | 6 +++--- .../current/compatibility.md | 10 ++++++++-- .../current/features/concurrency.md | 6 ++++++ .../current/features/continue-as-new.md | 2 ++ i18n/ja/source-hashes.json | 6 +++--- .../current/compatibility.md | 10 ++++++++-- .../current/features/concurrency.md | 6 ++++++ .../current/features/continue-as-new.md | 2 ++ i18n/pt-BR/source-hashes.json | 6 +++--- .../current/compatibility.md | 10 ++++++++-- .../current/features/concurrency.md | 6 ++++++ .../current/features/continue-as-new.md | 2 ++ i18n/uk/source-hashes.json | 6 +++--- .../current/compatibility.md | 10 ++++++++-- .../current/features/concurrency.md | 6 ++++++ .../current/features/continue-as-new.md | 2 ++ i18n/zh-Hans/source-hashes.json | 6 +++--- static/stable-releases.json | 2 +- 32 files changed, 150 insertions(+), 38 deletions(-) diff --git a/docs/compatibility.md b/docs/compatibility.md index 9fd4e02308b..fa765e6f3a8 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -99,12 +99,12 @@ The embedded package and the service-mode SDK have separate support contracts. | Package line | PHP | Laravel | | --- | --- | --- | -| Current embedded Workflow 2.27 | PHP 8.2+ in 8.x; PHP 8.3+ for Laravel 13 | `^12.69.0` or `^13.30.0` | +| Current embedded Workflow 2.28 | PHP 8.2+ in 8.x; PHP 8.3+ for Laravel 13 | `^12.69.0` or `^13.30.0` | | Embedded Workflow 2.20.5 | PHP `^8.1`, subject to Laravel's own minimum | `^10.50.4`, `^11.56.1`, `^12.69.0` or `^13.30.0` | | Published PHP SDK 3.14 | Bare SDK PHP `^8.1`; the Laravel bridge needs PHP `^8.2`, and PHP 8.3+ for Laravel 13 | `^12.69.0` or `^13.30.0` | | PHP SDK 3.9.5 | Bare SDK PHP `^8.1`; the Laravel bridge also follows Laravel's PHP minimum | `^10.50.4`, `^11.56.1`, `^12.69.0` or `^13.30.0` | -The [published embedded upgrade contract](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +The [published embedded upgrade contract](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) and each release's `composer.json` are the package authorities. The current embedded release was verified on Laravel 12 with PHP 8.2–8.4 and Laravel 13 with PHP 8.3–8.4. Its PHP 8.1 and Laravel 10/11 support has been removed. This does @@ -200,6 +200,12 @@ Workflow 2.27 keeps the 2.21 support floors and the embedded worker protocol `1. See the [2.27.0 release notes](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). +Workflow 2.28 keeps the 2.21 support floors and the embedded worker protocol `1.22`, and adds no database migration. Behavior change to check before upgrading: + +- From 2.28, a run that completes, fails or continues as new cancels the activities and timers it never awaited, such as `select()` losers, in the same transaction, instead of leaving them running. A late result from such an activity is refused with `run_closed`. If a workflow needs a loser's effect, await it before returning. See [Losers when the run closes](./features/concurrency.md#selection-losers-at-close). + +See the [2.28.0 release notes](https://github.com/durable-workflow/workflow/releases/tag/2.28.0). + ## Stability Levels Every public surface in Durable Workflow carries exactly one of these diff --git a/docs/features/concurrency.md b/docs/features/concurrency.md index 0329b76ea95..7430ae69816 100644 --- a/docs/features/concurrency.md +++ b/docs/features/concurrency.md @@ -149,6 +149,12 @@ idempotent. Concurrent inputs are ordered by their committed durable history; an input that arrives while an activity runs is visible on the next workflow task, and a late or duplicate input cannot replace an already recorded winner. +### Losers when the run closes {#selection-losers-at-close} + +From Workflow 2.28, if the run closes while a non-winning member is still open, the close cancels it in the same transaction. This applies when the run completes, fails or continues as new. An open activity gets `ActivityCancelled` with `cancellation_reason: run_closed`, and a pending timer gets `TimerCancelled`, both recorded before the terminal event. Nothing is appended after the terminal event, and a late result from the cancelled activity is refused. Replay ignores these cancellations, because the workflow never saw them. + +If the workflow needs a loser's effect, await the loser before returning. In service mode, an activity scheduled with `cancellation_policy: abandon` keeps running instead. The terminal event lists it under `abandoned_activities`, and its outcome is never recorded on the closed run. Child workflows follow their parent-close policy. + ## Nested Barriers Nested `all([...])` groups let one workflow step express a tree of durable fan-out and fan-in work. The runtime schedules every activity or child workflow as a durable leaf sequence, records the leaf's full `parallel_group_path`, waits until every enclosing barrier can make progress, and then rebuilds the original nested result shape before resuming the workflow body. During replay, an activity or child leaf from an `all([...])` step must still match that recorded group path; typed leaf history that has no group metadata is treated as incompatible older preview history instead of being guessed into the current barrier. diff --git a/docs/features/continue-as-new.md b/docs/features/continue-as-new.md index a1847fdb2c9..adf8b0e9c46 100644 --- a/docs/features/continue-as-new.md +++ b/docs/features/continue-as-new.md @@ -77,6 +77,8 @@ explicitly on the predecessor. Long-lived loops can shed history without inventing a new public workflow id every time the run rolls forward. +From Workflow 2.28, activities and timers the closing run never awaited are cancelled when it continues as new; children are handed to the continued run instead. See [Losers when the run closes](./concurrency.md#selection-losers-at-close). + ## History Budget {#history-budget} Workflow code can observe its current history length and a continue-as-new suggestion flag through explicit runtime context. This lets long-lived loops hand off deliberately before they hit history-budget cliffs. diff --git a/i18n/de/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/de/docusaurus-plugin-content-docs/current/compatibility.md index 743cb892e95..e35f50b0d9a 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/compatibility.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/compatibility.md @@ -66,12 +66,12 @@ Das eingebettete Paket und das Service-Modus-SDK haben eigene Supportverträge. | Paketlinie | PHP | Laravel | | --- | --- | --- | -| Aktuelles eingebettetes Workflow 2.27 | PHP 8.2+ in 8.x; PHP 8.3+ für Laravel 13 | `^12.69.0` oder `^13.30.0` | +| Aktuelles eingebettetes Workflow 2.28 | PHP 8.2+ in 8.x; PHP 8.3+ für Laravel 13 | `^12.69.0` oder `^13.30.0` | | Eingebettetes Workflow 2.20.5 | PHP `^8.1`, zusätzlich gilt das Framework-Minimum | `^10.50.4`, `^11.56.1`, `^12.69.0` oder `^13.30.0` | | Veröffentlichtes PHP-SDK 3.14 | Reines SDK PHP `^8.1`; die Laravel-Bridge benötigt PHP `^8.2` und für Laravel 13 PHP 8.3+ | `^12.69.0` oder `^13.30.0` | | PHP-SDK 3.9.5 | Reines SDK PHP `^8.1`; die Laravel-Bridge beachtet ebenfalls das Framework-Minimum | `^10.50.4`, `^11.56.1`, `^12.69.0` oder `^13.30.0` | -Maßgeblich sind der [veröffentlichte eingebettete Upgrade-Vertrag](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +Maßgeblich sind der [veröffentlichte eingebettete Upgrade-Vertrag](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) und die jeweilige `composer.json`. Das aktuelle eingebettete Release wurde mit Laravel 12/PHP 8.2–8.4 und Laravel 13/PHP 8.3–8.4 geprüft. Es entfernt PHP 8.1 und Laravel 10/11. Die [historische stabile v1-Anleitung](/docs/1.x/installation/) @@ -131,6 +131,12 @@ Workflow 2.27 behält die Mindestanforderungen von 2.21 und das eingebettete Wor Siehe die [Versionshinweise zu 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). +Workflow 2.28 behält die Mindestanforderungen von 2.21 und das eingebettete Worker-Protokoll `1.22` bei und fügt keine Datenbankmigration hinzu. Vor dem Upgrade zu prüfende Verhaltensänderung: + +- Ab 2.28 bricht ein Lauf, der abgeschlossen wird, fehlschlägt oder mit Continue-as-new fortgesetzt wird, die Aktivitäten und Timer, auf die er nie gewartet hat, etwa `select()`-Verlierer, in derselben Transaktion ab, statt sie weiterlaufen zu lassen. Ein verspätetes Ergebnis einer solchen Aktivität wird mit `run_closed` abgelehnt. Braucht ein Workflow die Wirkung eines Verlierers, warten Sie vor der Rückgabe auf ihn. Siehe [Verlierer beim Schließen des Laufs](./features/concurrency.md#selection-losers-at-close). + +Siehe die [Versionshinweise zu 2.28.0](https://github.com/durable-workflow/workflow/releases/tag/2.28.0). + ## Stabilitätsstufen {#stability-levels} Jede öffentliche Durable-Workflow-Schnittstelle trägt genau eine dieser Stabilitätsstufen. Die Stufen sind explizit: Eine nicht klassifizierte Schnittstelle ist nicht öffentlich. diff --git a/i18n/de/docusaurus-plugin-content-docs/current/features/concurrency.md b/i18n/de/docusaurus-plugin-content-docs/current/features/concurrency.md index 07328ad7077..c403c8ce3c4 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/features/concurrency.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/features/concurrency.md @@ -165,6 +165,12 @@ eintreffende Eingabe wird in der nächsten Workflow-Aufgabe sichtbar. Eine späte oder doppelte Eingabe kann keinen bereits aufgezeichneten Gewinner ersetzen. +### Verlierer beim Schließen des Laufs {#selection-losers-at-close} + +Ab Workflow 2.28 bricht das Schließen eines Laufs ein noch offenes, nicht gewinnendes Mitglied in derselben Transaktion ab. Das gilt, wenn der Lauf abgeschlossen wird, fehlschlägt oder mit Continue-as-new fortgesetzt wird. Eine offene Aktivität erhält `ActivityCancelled` mit `cancellation_reason: run_closed` und ein ausstehender Timer `TimerCancelled`, beide vor dem Abschlussereignis aufgezeichnet. Nach dem Abschlussereignis wird nichts mehr angehängt, und ein verspätetes Ergebnis der abgebrochenen Aktivität wird abgelehnt. Das Replay ignoriert diese Abbrüche, weil der Workflow sie nie gesehen hat. + +Braucht der Workflow die Wirkung eines Verlierers, warten Sie vor der Rückgabe auf ihn. Im Service-Modus läuft eine Aktivität, die mit `cancellation_policy: abandon` geplant wurde, stattdessen weiter. Das Abschlussereignis führt sie unter `abandoned_activities` auf, und ihr Ergebnis wird nie auf dem geschlossenen Lauf aufgezeichnet. Untergeordnete Workflows folgen ihrer Parent-close-Richtlinie. + ## Verschachtelte Barrieren {#nested-barriers} Verschachtelte `all([...])`-Gruppen lassen einen Workflow-Schritt einen Baum diff --git a/i18n/de/docusaurus-plugin-content-docs/current/features/continue-as-new.md b/i18n/de/docusaurus-plugin-content-docs/current/features/continue-as-new.md index f1f1999f3c1..e650ee085ee 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/features/continue-as-new.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/features/continue-as-new.md @@ -81,6 +81,8 @@ auf dem Vorgänger explizit abgeschlossen. Langlebige Schleifen können so ihre Historie abwerfen, ohne bei jedem Laufwechsel eine neue öffentliche Workflow-ID zu erfinden. +Ab Workflow 2.28 werden Aktivitäten und Timer, auf die der schließende Lauf nie gewartet hat, bei Continue-as-new abgebrochen; untergeordnete Workflows werden stattdessen an den fortgesetzten Lauf übergeben. Siehe [Verlierer beim Schließen des Laufs](./concurrency.md#selection-losers-at-close). + ## Historienbudget {#history-budget} Workflow-Code kann über expliziten Laufzeitkontext seine aktuelle diff --git a/i18n/de/source-hashes.json b/i18n/de/source-hashes.json index 3f24f58ae53..fb4faa26280 100644 --- a/i18n/de/source-hashes.json +++ b/i18n/de/source-hashes.json @@ -4,7 +4,7 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", + "compatibility.md": "d2e8f2add0f4e59823adbe8245bf8befa4820bc4ea51cbc96a0a07d62256cde6", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", @@ -33,9 +33,9 @@ "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", - "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", + "features/concurrency.md": "c6c10761dc0cd1bb167a385d4237412b8e81589e380a1b4f0d21ee4f03f74e76", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", - "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", + "features/continue-as-new.md": "63b6ac32d5371a57d48cca7594a93e73d3f24394fba18d8a808eefe6eff017fb", "features/events.md": "c466df05908748489226a3d1410c9203cf6f2986a4bb7539db1c5f82715abc7b", "features/external-payload-storage.md": "acc312fa2f50a43c96e1d235439124d28a7048f0bf3abac34319467fcbf7e898", "features/heartbeats.md": "4fce9636d68c89f29f259d52e463cd67eccf0bc55ad4d53338ed03329892b365", diff --git a/i18n/es/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/es/docusaurus-plugin-content-docs/current/compatibility.md index 0b7161ef913..68e9f3d9810 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/compatibility.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/compatibility.md @@ -100,12 +100,12 @@ El paquete integrado y el SDK de modo servicio tienen contratos distintos. | Línea del paquete | PHP | Laravel | | --- | --- | --- | -| Workflow integrado 2.27 actual | PHP 8.2+ de 8.x; PHP 8.3+ para Laravel 13 | `^12.69.0` o `^13.30.0` | +| Workflow integrado 2.28 actual | PHP 8.2+ de 8.x; PHP 8.3+ para Laravel 13 | `^12.69.0` o `^13.30.0` | | Workflow integrado 2.20.5 | PHP `^8.1`, sujeto al mínimo del framework | `^10.50.4`, `^11.56.1`, `^12.69.0` o `^13.30.0` | | SDK PHP 3.14 publicado | SDK básico PHP `^8.1`; el puente Laravel necesita PHP `^8.2`, y PHP 8.3+ para Laravel 13 | `^12.69.0` o `^13.30.0` | | SDK PHP 3.9.5 | SDK básico PHP `^8.1`; el puente Laravel también exige el mínimo del framework | `^10.50.4`, `^11.56.1`, `^12.69.0` o `^13.30.0` | -Las autoridades son el [contrato integrado publicado](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +Las autoridades son el [contrato integrado publicado](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) y el `composer.json` de cada versión. La versión integrada actual se verificó con Laravel 12/PHP 8.2–8.4 y Laravel 13/PHP 8.3–8.4. Retira PHP 8.1 y Laravel 10/11. No cambia la [guía histórica de v1 estable](/docs/1.x/installation/) @@ -164,6 +164,12 @@ Workflow 2.27 mantiene los mínimos de soporte de 2.21 y el protocolo de workers Consulte las [notas de la versión 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). +Workflow 2.28 mantiene los mínimos de soporte de 2.21 y el protocolo de workers integrado `1.22`, y no añade ninguna migración de base de datos. Cambio de comportamiento que conviene revisar antes de actualizar: + +- Desde 2.28, una ejecución que se completa, falla o continúa como nueva cancela en la misma transacción las actividades y los temporizadores que nunca esperó, como los perdedores de `select()`, en lugar de dejarlos en ejecución. Un resultado tardío de esa actividad se rechaza con `run_closed`. Si un workflow necesita el efecto de un perdedor, espérelo antes de retornar. Consulte [Perdedores cuando se cierra la ejecución](./features/concurrency.md#selection-losers-at-close). + +Consulte las [notas de la versión 2.28.0](https://github.com/durable-workflow/workflow/releases/tag/2.28.0). + ## Niveles de estabilidad {#stability-levels} Cada interfaz pública tiene exactamente uno de estos niveles de estabilidad. diff --git a/i18n/es/docusaurus-plugin-content-docs/current/features/concurrency.md b/i18n/es/docusaurus-plugin-content-docs/current/features/concurrency.md index 45941ffcbee..7c637bc8cc2 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/features/concurrency.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/features/concurrency.md @@ -118,6 +118,12 @@ El resultado contiene clave e índice estables del miembro, tipo e identidad dur El runtime registra la primera resolución apta mientras mantiene el bloqueo de confirmación del padre. Por eso, reinicios en frío, recargas del historial persistido, consultas y finalizaciones posteriores de perdedores reutilizan el ganador registrado, sin competir con futuros locales del lenguaje ni reinterpretar el orden. Las entregas exactamente duplicadas son idempotentes. Las entradas concurrentes se ordenan por historial duradero confirmado; una entrada que llega mientras corre una actividad es visible en la siguiente tarea de workflow, y una entrada tardía o duplicada no reemplaza al ganador registrado. +### Perdedores cuando se cierra la ejecución {#selection-losers-at-close} + +Desde Workflow 2.28, si la ejecución se cierra mientras un miembro no ganador sigue abierto, el cierre lo cancela en la misma transacción. Esto se aplica cuando la ejecución se completa, falla o continúa como nueva. Una actividad abierta recibe `ActivityCancelled` con `cancellation_reason: run_closed` y un temporizador pendiente recibe `TimerCancelled`, ambos registrados antes del evento terminal. No se añade nada después del evento terminal y se rechaza un resultado tardío de la actividad cancelada. El replay ignora estas cancelaciones, porque el workflow nunca las vio. + +Si el workflow necesita el efecto de un perdedor, espérelo antes de retornar. En el modo de servicio, una actividad programada con `cancellation_policy: abandon` sigue ejecutándose. El evento terminal la incluye en `abandoned_activities`, y su resultado nunca se registra en la ejecución cerrada. Los workflows hijos siguen su política de cierre del padre. + ## Barreras anidadas {#nested-barriers} Los grupos anidados `all([...])` permiten expresar en un paso un árbol duradero de distribución y reunión de trabajo. El runtime programa cada actividad o hijo como secuencia hoja duradera, registra su `parallel_group_path` completo, espera hasta que todas las barreras que la contienen puedan avanzar y reconstruye la forma anidada original del resultado antes de reanudar. Al reproducir, cada hoja de actividad o hijo debe coincidir con esa ruta registrada. El historial tipado de hojas sin metadatos de grupo se considera historial incompatible de una versión preliminar antigua, sin suponer su encaje en la barrera actual. diff --git a/i18n/es/docusaurus-plugin-content-docs/current/features/continue-as-new.md b/i18n/es/docusaurus-plugin-content-docs/current/features/continue-as-new.md index 47d8cbb6d1a..a2f013b2d4f 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/features/continue-as-new.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/features/continue-as-new.md @@ -66,6 +66,8 @@ Una señal dirigida a una ejecución nunca cambia de destino. Si no puede aplica Los bucles prolongados pueden desprenderse del historial sin inventar otro id público de workflow en cada transición. +Desde Workflow 2.28, las actividades y los temporizadores que la ejecución que se cierra nunca esperó se cancelan al continuar como nueva ejecución; los hijos, en cambio, se entregan a la ejecución continuada. Consulte [Perdedores cuando se cierra la ejecución](./concurrency.md#selection-losers-at-close). + ## Presupuesto de historial {#history-budget} El código puede observar la longitud actual del historial y una sugerencia de continuación mediante contexto explícito del runtime. Así puede traspasar deliberadamente antes de alcanzar límites costosos. diff --git a/i18n/es/source-hashes.json b/i18n/es/source-hashes.json index 3f24f58ae53..fb4faa26280 100644 --- a/i18n/es/source-hashes.json +++ b/i18n/es/source-hashes.json @@ -4,7 +4,7 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", + "compatibility.md": "d2e8f2add0f4e59823adbe8245bf8befa4820bc4ea51cbc96a0a07d62256cde6", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", @@ -33,9 +33,9 @@ "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", - "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", + "features/concurrency.md": "c6c10761dc0cd1bb167a385d4237412b8e81589e380a1b4f0d21ee4f03f74e76", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", - "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", + "features/continue-as-new.md": "63b6ac32d5371a57d48cca7594a93e73d3f24394fba18d8a808eefe6eff017fb", "features/events.md": "c466df05908748489226a3d1410c9203cf6f2986a4bb7539db1c5f82715abc7b", "features/external-payload-storage.md": "acc312fa2f50a43c96e1d235439124d28a7048f0bf3abac34319467fcbf7e898", "features/heartbeats.md": "4fce9636d68c89f29f259d52e463cd67eccf0bc55ad4d53338ed03329892b365", diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/fr/docusaurus-plugin-content-docs/current/compatibility.md index 0b294c641ea..41821b73c75 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/compatibility.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/compatibility.md @@ -96,12 +96,12 @@ embarqué et le SDK en mode service ont des contrats distincts. | Branche du paquet | PHP | Laravel | | --- | --- | --- | -| Workflow embarqué 2.27 actuel | PHP 8.2+ en 8.x ; PHP 8.3+ pour Laravel 13 | `^12.69.0` ou `^13.30.0` | +| Workflow embarqué 2.28 actuel | PHP 8.2+ en 8.x ; PHP 8.3+ pour Laravel 13 | `^12.69.0` ou `^13.30.0` | | Workflow embarqué 2.20.5 | PHP `^8.1`, sous réserve du minimum du framework | `^10.50.4`, `^11.56.1`, `^12.69.0` ou `^13.30.0` | | SDK PHP 3.14 publié | SDK de base PHP `^8.1` ; le pont Laravel exige PHP `^8.2`, et PHP 8.3+ pour Laravel 13 | `^12.69.0` ou `^13.30.0` | | SDK PHP 3.9.5 | SDK de base PHP `^8.1` ; le pont Laravel suit aussi le minimum du framework | `^10.50.4`, `^11.56.1`, `^12.69.0` ou `^13.30.0` | -Le [contrat embarqué publié](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +Le [contrat embarqué publié](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) et le `composer.json` de chaque version font autorité. La version embarquée actuelle a été vérifiée sur Laravel 12/PHP 8.2–8.4 et Laravel 13/PHP 8.3–8.4. Elle retire PHP 8.1 et Laravel 10/11. Le [guide historique v1 stable](/docs/1.x/installation/) @@ -160,6 +160,12 @@ Workflow 2.27 conserve les planchers de support de 2.21 et le protocole de worke Voir les [notes de version de 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). +Workflow 2.28 conserve les planchers de support de 2.21 et le protocole de worker embarqué `1.22`, et n'ajoute aucune migration de base de données. Changement de comportement à vérifier avant la mise à niveau : + +- Depuis 2.28, une exécution qui se termine, échoue ou continue dans une nouvelle exécution annule dans la même transaction les activités et minuteurs qu'elle n'a jamais attendus, comme les perdants de `select()`, au lieu de les laisser s'exécuter. Un résultat tardif d'une telle activité est refusé avec `run_closed`. Si un workflow a besoin de l'effet d'un perdant, attendez-le avant de retourner. Voir [Perdants à la clôture de l’exécution](./features/concurrency.md#selection-losers-at-close). + +Voir les [notes de version de 2.28.0](https://github.com/durable-workflow/workflow/releases/tag/2.28.0). + ## Niveaux de stabilité {#stability-levels} Chaque interface publique Durable Workflow porte exactement un de ces niveaux. diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/features/concurrency.md b/i18n/fr/docusaurus-plugin-content-docs/current/features/concurrency.md index c3af44b08e4..d3c5456cdb7 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/features/concurrency.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/features/concurrency.md @@ -154,6 +154,12 @@ historique durable validé. Une entrée arrivant pendant une activité est visib à la prochaine tâche de workflow ; une entrée tardive ou dupliquée ne remplace pas un gagnant déjà enregistré. +### Perdants à la clôture de l’exécution {#selection-losers-at-close} + +Depuis Workflow 2.28, si l’exécution se clôt alors qu’un membre non gagnant est encore ouvert, la clôture l’annule dans la même transaction. Cela s’applique quand l’exécution se termine, échoue ou continue dans une nouvelle exécution. Une activité ouverte reçoit `ActivityCancelled` avec `cancellation_reason: run_closed`, et un minuteur en attente reçoit `TimerCancelled`, tous deux enregistrés avant l’événement terminal. Rien n’est ajouté après l’événement terminal, et un résultat tardif de l’activité annulée est refusé. Le replay ignore ces annulations, car le workflow ne les a jamais vues. + +Si le workflow a besoin de l’effet d’un perdant, attendez-le avant de retourner. En mode service, une activité planifiée avec `cancellation_policy: abandon` continue de s’exécuter. L’événement terminal la liste dans `abandoned_activities`, et son résultat n’est jamais enregistré sur l’exécution close. Les workflows enfants suivent leur politique de clôture du parent. + ## Barrières imbriquées {#nested-barriers} Les groupes `all([...])` imbriqués expriment dans une étape un arbre de travail durable distribué puis regroupé. Le runtime programme chaque activité ou enfant comme une séquence feuille durable, enregistre son `parallel_group_path` complet, attend que chaque barrière englobante puisse avancer puis reconstruit la structure imbriquée initiale avant de reprendre le workflow. À la relecture, une feuille d’activité ou d’enfant d’une étape `all([...])` doit toujours correspondre au chemin enregistré. Un historique typé de feuille sans métadonnées de groupe est traité comme un ancien historique de préversion incompatible, sans rattachement supposé à la barrière actuelle. diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/features/continue-as-new.md b/i18n/fr/docusaurus-plugin-content-docs/current/features/continue-as-new.md index b44789bf521..df87b0bca12 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/features/continue-as-new.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/features/continue-as-new.md @@ -78,6 +78,8 @@ se clôturent explicitement sur le prédécesseur. Les boucles longues peuvent réduire leur historique sans inventer un nouvel identifiant public de workflow à chaque passage à l’exécution suivante. +Depuis Workflow 2.28, les activités et minuteurs que l’exécution qui se clôt n’a jamais attendus sont annulés lorsqu’elle continue dans une nouvelle exécution ; les enfants sont en revanche transmis à l’exécution suivante. Voir [Perdants à la clôture de l’exécution](./concurrency.md#selection-losers-at-close). + ## Budget d’historique {#history-budget} Le code du workflow peut consulter la longueur courante de l’historique et un indicateur de recommandation de continuation via un contexte explicite du runtime. Les boucles longues peuvent ainsi passer le relais volontairement avant d’atteindre des limites de budget d’historique. diff --git a/i18n/fr/source-hashes.json b/i18n/fr/source-hashes.json index 3f24f58ae53..fb4faa26280 100644 --- a/i18n/fr/source-hashes.json +++ b/i18n/fr/source-hashes.json @@ -4,7 +4,7 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", + "compatibility.md": "d2e8f2add0f4e59823adbe8245bf8befa4820bc4ea51cbc96a0a07d62256cde6", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", @@ -33,9 +33,9 @@ "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", - "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", + "features/concurrency.md": "c6c10761dc0cd1bb167a385d4237412b8e81589e380a1b4f0d21ee4f03f74e76", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", - "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", + "features/continue-as-new.md": "63b6ac32d5371a57d48cca7594a93e73d3f24394fba18d8a808eefe6eff017fb", "features/events.md": "c466df05908748489226a3d1410c9203cf6f2986a4bb7539db1c5f82715abc7b", "features/external-payload-storage.md": "acc312fa2f50a43c96e1d235439124d28a7048f0bf3abac34319467fcbf7e898", "features/heartbeats.md": "4fce9636d68c89f29f259d52e463cd67eccf0bc55ad4d53338ed03329892b365", diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/ja/docusaurus-plugin-content-docs/current/compatibility.md index 3adc4f4738a..d9d53259ca4 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/compatibility.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/compatibility.md @@ -66,12 +66,12 @@ PHP と Laravel の要件を比較する前にパッケージのリリースを | パッケージ系列 | PHP | Laravel | | --- | --- | --- | -| 現在の組み込み Workflow 2.27 | 8.x 系の PHP 8.2 以降。Laravel 13 は PHP 8.3 以降 | `^12.69.0` または `^13.30.0` | +| 現在の組み込み Workflow 2.28 | 8.x 系の PHP 8.2 以降。Laravel 13 は PHP 8.3 以降 | `^12.69.0` または `^13.30.0` | | 組み込み Workflow 2.20.5 | PHP `^8.1`。Laravel 自身の最低要件も適用 | `^10.50.4`、`^11.56.1`、`^12.69.0` または `^13.30.0` | | 公開済み PHP SDK 3.14 | 基本 SDK は PHP `^8.1`。Laravel ブリッジは PHP `^8.2` が必要で、Laravel 13 は PHP 8.3 以降 | `^12.69.0` または `^13.30.0` | | PHP SDK 3.9.5 | 基本 SDK は PHP `^8.1`。Laravel ブリッジはフレームワークの最低要件にも従う | `^10.50.4`、`^11.56.1`、`^12.69.0` または `^13.30.0` | -[公開済み組み込みアップグレード契約](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +[公開済み組み込みアップグレード契約](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) と各リリースの `composer.json` がパッケージの根拠です。現在の組み込みリリースは Laravel 12/PHP 8.2~8.4 と Laravel 13/PHP 8.3~8.4 で検証されています。 PHP 8.1 と Laravel 10/11 のサポートは終了しました。 @@ -127,6 +127,12 @@ Workflow 2.27 は 2.21 のサポート下限と組み込みワーカープロト [2.27.0 のリリースノート](https://github.com/durable-workflow/workflow/releases/tag/2.27.0)を参照してください。 +Workflow 2.28 は 2.21 のサポート下限と組み込みワーカープロトコル `1.22` を維持し、データベースマイグレーションは追加しません。アップグレード前に確認すべき動作の変更: + +- 2.28 以降、完了、失敗、または continue-as-new する実行は、`select()` の敗者など一度も待たなかったアクティビティとタイマーを、実行し続けさせるのではなく同じトランザクション内でキャンセルします。そのようなアクティビティからの遅れた結果は `run_closed` で拒否されます。ワークフローが敗者の効果を必要とする場合は、戻る前にそれを待ってください。[実行が閉じるときの敗者](./features/concurrency.md#selection-losers-at-close)を参照してください。 + +[2.28.0 のリリースノート](https://github.com/durable-workflow/workflow/releases/tag/2.28.0)を参照してください。 + ## 安定性レベル {#stability-levels} Durable Workflow の各公開インターフェースは、次の安定性レベルを厳密に一つ持ちます。分類は明示的です。未分類のインターフェースは公開ではありません。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/features/concurrency.md b/i18n/ja/docusaurus-plugin-content-docs/current/features/concurrency.md index 7ca308cdb78..2609a57ac30 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/features/concurrency.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/features/concurrency.md @@ -118,6 +118,12 @@ final class ResolveInRealTime extends Workflow ランタイムは親実行のコミットロック中に最初の対象解決を記録します。コールド再起動、保存履歴の再読込、クエリ、後の非勝者完了は、言語ローカルな Future を競わせたり履歴順を解釈し直したりせず記録済み勝者を再利用します。完全な重複配信は冪等です。同時入力はコミット済み永続履歴で順序付けられ、アクティビティ中の入力は次のタスクで見えます。遅延・重複入力で記録済み勝者は置換しません。 +### 実行が閉じるときの敗者 {#selection-losers-at-close} + +Workflow 2.28 以降、勝者でないメンバーが開いたまま実行が閉じると、その終了処理が同じトランザクション内でそのメンバーをキャンセルします。これは実行の完了、失敗、continue-as-new のいずれにも当てはまります。開いているアクティビティには `cancellation_reason: run_closed` 付きの `ActivityCancelled` が、保留中のタイマーには `TimerCancelled` が、どちらも終了イベントの前に記録されます。終了イベントの後には何も追加されず、キャンセルされたアクティビティからの遅れた結果は拒否されます。ワークフローはこれらのキャンセルを観測していないため、リプレイはそれらを無視します。 + +ワークフローが敗者の効果を必要とする場合は、戻る前にその敗者を待ってください。サービスモードでは、`cancellation_policy: abandon` でスケジュールされたアクティビティは代わりに実行を続けます。終了イベントはそれを `abandoned_activities` に列挙し、その結果が閉じた実行に記録されることはありません。子ワークフローは親クローズポリシーに従います。 + ## 入れ子のバリア {#nested-barriers} 入れ子の `all([...])` は1ステップで永続的な fan-out/fan-in の木を表します。各アクティビティや子を永続的な葉シーケンスとしてスケジュールし、完全な `parallel_group_path` を記録し、囲む各バリアが進めるまで待って、元の結果構造を復元します。リプレイでは葉が記録済み経路と一致する必要があります。グループ情報のない型付き葉履歴は推測で割り当てず、非互換の旧プレビュー履歴として扱います。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/features/continue-as-new.md b/i18n/ja/docusaurus-plugin-content-docs/current/features/continue-as-new.md index 08548f05db4..e57e3b46b83 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/features/continue-as-new.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/features/continue-as-new.md @@ -66,6 +66,8 @@ Core 2.7.0 と互換 Server は、実行のコマンド契約にハンドラー 長期ループは、実行が進むたびに公開 ID を作り直さずに履歴を減らせます。 +Workflow 2.28 以降、閉じる実行が待たなかったアクティビティとタイマーは continue-as-new の時点でキャンセルされます。子ワークフローは代わりに継続後の実行に引き渡されます。[実行が閉じるときの敗者](./concurrency.md#selection-losers-at-close)を参照してください。 + ## 履歴の使用量上限 {#history-budget} ワークフローコードは明示的なランタイムコンテキストから現在の履歴長と継続推奨フラグを参照できます。長期ループが履歴の使用量上限に達する前に、計画的に引き継げます。 diff --git a/i18n/ja/source-hashes.json b/i18n/ja/source-hashes.json index 3f24f58ae53..fb4faa26280 100644 --- a/i18n/ja/source-hashes.json +++ b/i18n/ja/source-hashes.json @@ -4,7 +4,7 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", + "compatibility.md": "d2e8f2add0f4e59823adbe8245bf8befa4820bc4ea51cbc96a0a07d62256cde6", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", @@ -33,9 +33,9 @@ "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", - "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", + "features/concurrency.md": "c6c10761dc0cd1bb167a385d4237412b8e81589e380a1b4f0d21ee4f03f74e76", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", - "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", + "features/continue-as-new.md": "63b6ac32d5371a57d48cca7594a93e73d3f24394fba18d8a808eefe6eff017fb", "features/events.md": "c466df05908748489226a3d1410c9203cf6f2986a4bb7539db1c5f82715abc7b", "features/external-payload-storage.md": "acc312fa2f50a43c96e1d235439124d28a7048f0bf3abac34319467fcbf7e898", "features/heartbeats.md": "4fce9636d68c89f29f259d52e463cd67eccf0bc55ad4d53338ed03329892b365", diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/compatibility.md index 2ad30878f0d..2838b576971 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/compatibility.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/compatibility.md @@ -101,12 +101,12 @@ O pacote embutido e o SDK de modo de serviço têm contratos separados. | Linha do pacote | PHP | Laravel | | --- | --- | --- | -| Workflow embutido 2.27 atual | PHP 8.2+ da linha 8.x; PHP 8.3+ para Laravel 13 | `^12.69.0` ou `^13.30.0` | +| Workflow embutido 2.28 atual | PHP 8.2+ da linha 8.x; PHP 8.3+ para Laravel 13 | `^12.69.0` ou `^13.30.0` | | Workflow embutido 2.20.5 | PHP `^8.1`, respeitando o mínimo do framework | `^10.50.4`, `^11.56.1`, `^12.69.0` ou `^13.30.0` | | SDK PHP 3.14 publicado | SDK básico PHP `^8.1`; a ponte Laravel exige PHP `^8.2`, e PHP 8.3+ para Laravel 13 | `^12.69.0` ou `^13.30.0` | | SDK PHP 3.9.5 | SDK básico PHP `^8.1`; a ponte Laravel também segue o mínimo do framework | `^10.50.4`, `^11.56.1`, `^12.69.0` ou `^13.30.0` | -As autoridades são o [contrato embutido publicado](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +As autoridades são o [contrato embutido publicado](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) e o `composer.json` de cada versão. A versão embutida atual foi verificada com Laravel 12/PHP 8.2–8.4 e Laravel 13/PHP 8.3–8.4. Ela remove suporte a PHP 8.1 e Laravel 10/11. Isso preserva o [guia histórico do v1 estável](/docs/1.x/installation/) @@ -164,6 +164,12 @@ O Workflow 2.27 mantém os pisos de suporte do 2.21 e o protocolo de workers emb Veja as [notas da versão 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). +O Workflow 2.28 mantém os pisos de suporte do 2.21 e o protocolo de workers embutido `1.22`, e não adiciona migração de banco de dados. Mudança de comportamento para verificar antes de atualizar: + +- A partir do 2.28, uma execução que é concluída, falha ou continua como nova cancela na mesma transação as atividades e timers que nunca aguardou, como os perdedores de `select()`, em vez de deixá-los em execução. Um resultado tardio dessa atividade é recusado com `run_closed`. Se um workflow precisa do efeito de um perdedor, aguarde-o antes de retornar. Veja [Perdedores quando a execução é encerrada](./features/concurrency.md#selection-losers-at-close). + +Veja as [notas da versão 2.28.0](https://github.com/durable-workflow/workflow/releases/tag/2.28.0). + ## Níveis de estabilidade {#stability-levels} Cada interface pública do Durable Workflow tem exatamente um destes níveis. diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/concurrency.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/concurrency.md index c76bdd7f09c..c4570a6df0a 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/concurrency.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/concurrency.md @@ -154,6 +154,12 @@ confirmado. Uma entrada que chega enquanto uma atividade executa fica visível na próxima tarefa de workflow, e uma entrada tardia ou duplicada não pode substituir um vencedor já registrado. +### Perdedores quando a execução é encerrada {#selection-losers-at-close} + +A partir do Workflow 2.28, se a execução é encerrada enquanto um membro não vencedor ainda está aberto, o encerramento o cancela na mesma transação. Isso vale quando a execução é concluída, falha ou continua como nova. Uma atividade aberta recebe `ActivityCancelled` com `cancellation_reason: run_closed`, e um timer pendente recebe `TimerCancelled`, ambos registrados antes do evento terminal. Nada é anexado depois do evento terminal, e um resultado tardio da atividade cancelada é recusado. O replay ignora esses cancelamentos, porque o workflow nunca os viu. + +Se o workflow precisa do efeito de um perdedor, aguarde-o antes de retornar. No modo de serviço, uma atividade agendada com `cancellation_policy: abandon` continua em execução. O evento terminal a lista em `abandoned_activities`, e seu resultado nunca é registrado na execução encerrada. Workflows filhos seguem sua política de encerramento do pai. + ## Barreiras aninhadas {#nested-barriers} Grupos `all([...])` aninhados permitem que uma etapa de workflow expresse uma árvore durável de ramificação e convergência de trabalho. O runtime agenda cada atividade ou workflow filho como uma sequência durável de folha, registra o `parallel_group_path` completo da folha, espera até que cada barreira envolvente possa avançar e então reconstrói o formato aninhado original dos resultados antes de retomar o corpo do workflow. Durante o replay, uma folha de atividade ou de filho de uma etapa `all([...])` ainda deve corresponder ao caminho de grupo registrado. Histórico tipado de folha sem metadados de grupo é tratado como histórico incompatível de uma prévia antiga, sem tentar adivinhar sua posição na barreira atual. diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/continue-as-new.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/continue-as-new.md index 397f176db05..a1b0ae113bf 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/continue-as-new.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/continue-as-new.md @@ -78,6 +78,8 @@ são encerrados explicitamente na execução antecessora. Loops de longa duração podem limitar o histórico por execução sem inventar um novo ID público de workflow a cada avanço para uma nova execução. +A partir do Workflow 2.28, atividades e timers que a execução que está sendo encerrada nunca aguardou são cancelados quando ela continua como nova; os filhos, por outro lado, são transferidos para a nova execução. Veja [Perdedores quando a execução é encerrada](./concurrency.md#selection-losers-at-close). + ## Limites do histórico {#history-budget} O código do workflow pode observar o tamanho atual do histórico e um indicador de sugestão de continuar como novo por meio do contexto explícito do runtime. Isso permite que loops de longa duração façam a transferência deliberadamente antes de atingir os limites do histórico. diff --git a/i18n/pt-BR/source-hashes.json b/i18n/pt-BR/source-hashes.json index 3f24f58ae53..fb4faa26280 100644 --- a/i18n/pt-BR/source-hashes.json +++ b/i18n/pt-BR/source-hashes.json @@ -4,7 +4,7 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", + "compatibility.md": "d2e8f2add0f4e59823adbe8245bf8befa4820bc4ea51cbc96a0a07d62256cde6", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", @@ -33,9 +33,9 @@ "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", - "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", + "features/concurrency.md": "c6c10761dc0cd1bb167a385d4237412b8e81589e380a1b4f0d21ee4f03f74e76", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", - "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", + "features/continue-as-new.md": "63b6ac32d5371a57d48cca7594a93e73d3f24394fba18d8a808eefe6eff017fb", "features/events.md": "c466df05908748489226a3d1410c9203cf6f2986a4bb7539db1c5f82715abc7b", "features/external-payload-storage.md": "acc312fa2f50a43c96e1d235439124d28a7048f0bf3abac34319467fcbf7e898", "features/heartbeats.md": "4fce9636d68c89f29f259d52e463cd67eccf0bc55ad4d53338ed03329892b365", diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/uk/docusaurus-plugin-content-docs/current/compatibility.md index bb1551d5a03..9bcf5fbbfdc 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/compatibility.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/compatibility.md @@ -98,12 +98,12 @@ OpenAPI, AsyncAPI чи JSON Schema. Schema | Лінійка пакета | PHP | Laravel | | --- | --- | --- | -| Поточний вбудований Workflow 2.27 | PHP 8.2+ у 8.x; PHP 8.3+ для Laravel 13 | `^12.69.0` або `^13.30.0` | +| Поточний вбудований Workflow 2.28 | PHP 8.2+ у 8.x; PHP 8.3+ для Laravel 13 | `^12.69.0` або `^13.30.0` | | Вбудований Workflow 2.20.5 | PHP `^8.1` з урахуванням мінімуму фреймворку | `^10.50.4`, `^11.56.1`, `^12.69.0` або `^13.30.0` | | Опублікований PHP SDK 3.14 | Базовий SDK PHP `^8.1`; міст Laravel потребує PHP `^8.2`, а для Laravel 13 — PHP 8.3+ | `^12.69.0` або `^13.30.0` | | PHP SDK 3.9.5 | Базовий SDK PHP `^8.1`; міст Laravel також дотримується мінімуму фреймворку | `^10.50.4`, `^11.56.1`, `^12.69.0` або `^13.30.0` | -Першоджерела пакета — [опублікований контракт вбудованого оновлення](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +Першоджерела пакета — [опублікований контракт вбудованого оновлення](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) і `composer.json` кожного випуску. Поточний вбудований випуск перевірено з Laravel 12/PHP 8.2–8.4 та Laravel 13/PHP 8.3–8.4. Підтримку PHP 8.1 і Laravel 10/11 вилучено. [Історичний посібник стабільної v1](/docs/1.x/installation/) та @@ -159,6 +159,12 @@ Workflow 2.27 зберігає мінімальні вимоги підтрим Див. [примітки до випуску 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). +Workflow 2.28 зберігає мінімальні вимоги підтримки з 2.21 і протокол вбудованого worker `1.22` та не додає міграцій бази даних. Зміна поведінки, яку варто перевірити перед оновленням: + +- Починаючи з 2.28, запуск, який завершується, зазнає збою або виконує continue-as-new, скасовує в тій самій транзакції активності й таймери, на які він ніколи не чекав, наприклад учасників `select()`, що програли, замість того щоб залишати їх працювати. Запізнілий результат такої активності відхиляється з `run_closed`. Якщо workflow потрібен ефект учасника, що програв, дочекайтеся його до повернення. Див. [Учасники, що програли, під час закриття запуску](./features/concurrency.md#selection-losers-at-close). + +Див. [примітки до випуску 2.28.0](https://github.com/durable-workflow/workflow/releases/tag/2.28.0). + ## Рівні стабільності {#stability-levels} Кожна публічна поверхня Durable Workflow має рівно один із цих рівнів diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/features/concurrency.md b/i18n/uk/docusaurus-plugin-content-docs/current/features/concurrency.md index 3b1ecaf0d59..7428e27f73e 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/features/concurrency.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/features/concurrency.md @@ -154,6 +154,12 @@ Runtime записує перший придатний результат, ут завданні workflow. Пізні або повторні дані не можуть замінити вже записаного переможця. +### Учасники, що програли, під час закриття запуску {#selection-losers-at-close} + +Починаючи з Workflow 2.28, якщо запуск закривається, поки учасник, що не переміг, ще відкритий, закриття скасовує його в тій самій транзакції. Це стосується завершення запуску, збою або continue-as-new. Відкрита активність отримує `ActivityCancelled` з `cancellation_reason: run_closed`, а таймер в очікуванні отримує `TimerCancelled`; обидві події записуються до завершальної. Після завершальної події нічого не додається, а запізнілий результат скасованої активності відхиляється. Повторне відтворення ігнорує ці скасування, бо workflow їх ніколи не бачив. + +Якщо workflow потрібен ефект учасника, що програв, дочекайтеся його до повернення. У сервісному режимі активність, заплановану з `cancellation_policy: abandon`, натомість продовжує працювати. Завершальна подія перелічує її в `abandoned_activities`, а її результат ніколи не записується в закритий запуск. Дочірні workflow дотримуються своєї політики закриття батьківського workflow. + ## Вкладені бар’єри {#nested-barriers} Вкладені групи `all([...])` дають одному кроку workflow змогу описати дерево стійкого розгалуження роботи й збирання результатів. Runtime планує кожну activity або дочірній workflow як стійку листову послідовність, записує повний `parallel_group_path` листка й очікує, доки кожен охоплюючий бар’єр зможе просунутися. Потім він відновлює початкову вкладену структуру результатів перед продовженням тіла workflow. Під час replay листок activity або дочірнього workflow з кроку `all([...])` має відповідати записаному шляху групи. Типізована історія листка без метаданих групи вважається несумісною історією старої попередньої версії, а не підставляється в поточний бар’єр за припущенням. diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/features/continue-as-new.md b/i18n/uk/docusaurus-plugin-content-docs/current/features/continue-as-new.md index 69aa08170e6..c8a4e154efb 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/features/continue-as-new.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/features/continue-as-new.md @@ -78,6 +78,8 @@ Core 2.7.0 і сумісні Server зберігають прийняті сиг Тривалі цикли можуть звільнятися від накопиченої історії без створення нового публічного ID workflow за кожного переходу запуску. +Починаючи з Workflow 2.28, активності й таймери, на які запуск, що закривається, ніколи не чекав, скасовуються під час continue-as-new; дочірні workflow натомість передаються продовженому запуску. Див. [Учасники, що програли, під час закриття запуску](./concurrency.md#selection-losers-at-close). + ## Бюджет історії {#history-budget} Код workflow може перевіряти поточну довжину історії та прапорець рекомендації continue-as-new через явний контекст runtime. Це дає тривалим циклам змогу свідомо передавати виконання до досягнення граничного бюджету історії. diff --git a/i18n/uk/source-hashes.json b/i18n/uk/source-hashes.json index 3f24f58ae53..fb4faa26280 100644 --- a/i18n/uk/source-hashes.json +++ b/i18n/uk/source-hashes.json @@ -4,7 +4,7 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", + "compatibility.md": "d2e8f2add0f4e59823adbe8245bf8befa4820bc4ea51cbc96a0a07d62256cde6", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", @@ -33,9 +33,9 @@ "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", - "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", + "features/concurrency.md": "c6c10761dc0cd1bb167a385d4237412b8e81589e380a1b4f0d21ee4f03f74e76", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", - "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", + "features/continue-as-new.md": "63b6ac32d5371a57d48cca7594a93e73d3f24394fba18d8a808eefe6eff017fb", "features/events.md": "c466df05908748489226a3d1410c9203cf6f2986a4bb7539db1c5f82715abc7b", "features/external-payload-storage.md": "acc312fa2f50a43c96e1d235439124d28a7048f0bf3abac34319467fcbf7e898", "features/heartbeats.md": "4fce9636d68c89f29f259d52e463cd67eccf0bc55ad4d53338ed03329892b365", diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/compatibility.md index 539d91bde8a..739b038e552 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/compatibility.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/compatibility.md @@ -65,12 +65,12 @@ import protocolCatalog from '@site/static/platform-protocol-specs.json'; | 包版本线 | PHP | Laravel | | --- | --- | --- | -| 当前嵌入式 Workflow 2.27 | PHP 8.x 中的 8.2+;Laravel 13 需要 PHP 8.3+ | `^12.69.0` 或 `^13.30.0` | +| 当前嵌入式 Workflow 2.28 | PHP 8.x 中的 8.2+;Laravel 13 需要 PHP 8.3+ | `^12.69.0` 或 `^13.30.0` | | 嵌入式 Workflow 2.20.5 | PHP `^8.1`,并满足框架自身最低要求 | `^10.50.4`、`^11.56.1`、`^12.69.0` 或 `^13.30.0` | | 已发布 PHP SDK 3.14 | 基础 SDK 为 PHP `^8.1`;Laravel 桥接需要 PHP `^8.2`,Laravel 13 需要 PHP 8.3+ | `^12.69.0` 或 `^13.30.0` | | PHP SDK 3.9.5 | 基础 SDK 为 PHP `^8.1`;Laravel 桥接还需满足框架的 PHP 要求 | `^10.50.4`、`^11.56.1`、`^12.69.0` 或 `^13.30.0` | -包的依据是[已发布的嵌入式升级契约](https://github.com/durable-workflow/workflow/blob/2.27.0/resources/laravel-embedded-upgrade-contract.json) +包的依据是[已发布的嵌入式升级契约](https://github.com/durable-workflow/workflow/blob/2.28.0/resources/laravel-embedded-upgrade-contract.json) 及各版本的 `composer.json`。当前嵌入式版本已验证 Laravel 12/PHP 8.2–8.4 与 Laravel 13/PHP 8.3–8.4, 不再支持 PHP 8.1 和 Laravel 10/11。[历史稳定 v1 安装指南](/docs/1.x/installation/)与 [PHP SDK 的独立要求](https://php.durable-workflow.com/)保持独立。 @@ -118,6 +118,12 @@ Workflow 2.27 保持 2.21 的支持下限和嵌入式 worker 协议 `1.22`,不 参见 [2.27.0 发布说明](https://github.com/durable-workflow/workflow/releases/tag/2.27.0)。 +Workflow 2.28 保持 2.21 的支持下限和嵌入式 worker 协议 `1.22`,不新增数据库迁移。升级前需要检查的行为变更: + +- 从 2.28 起,完成、失败或 continue-as-new 的运行会在同一事务中取消它从未等待的活动和计时器(例如 `select()` 的落选成员),而不是让它们继续运行。此类活动的迟到结果会以 `run_closed` 被拒绝。如果工作流需要某个落选成员的效果,请在返回之前等待它。参见[运行关闭时的落选成员](./features/concurrency.md#selection-losers-at-close)。 + +参见 [2.28.0 发布说明](https://github.com/durable-workflow/workflow/releases/tag/2.28.0)。 + ## 稳定性级别 {#stability-levels} Durable Workflow 中每个公开接口恰好具有以下一个稳定性级别。级别必须明确;未分类的接口不是公开接口。 diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/concurrency.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/concurrency.md index facb8d83391..00c42375a89 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/concurrency.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/concurrency.md @@ -118,6 +118,12 @@ final class ResolveInRealTime extends Workflow 运行时在持有父运行提交锁时记录首个符合条件的解决结果。冷重启、持久历史重新加载、查询重放以及后续未胜出成员的完成,都会复用已记录胜出者,不会竞争本地语言 Future 或重新解释历史顺序。完全相同的重复投递是幂等的。并发输入按已提交持久历史排序;活动运行期间到达的输入在下一工作流任务中可见,迟到或重复输入无法替换已记录的胜出者。 +### 运行关闭时的落选成员 {#selection-losers-at-close} + +从 Workflow 2.28 起,如果运行在某个未胜出的成员仍处于打开状态时关闭,关闭操作会在同一事务中取消它。这适用于运行完成、失败或 continue-as-new 的情况。打开的活动会记录带有 `cancellation_reason: run_closed` 的 `ActivityCancelled`,待处理的计时器会记录 `TimerCancelled`,两者都在终止事件之前记录。终止事件之后不会再追加任何内容,已取消活动的迟到结果会被拒绝。由于工作流从未观察到这些取消,重放会忽略它们。 + +如果工作流需要某个落选成员的效果,请在返回之前等待它。在服务模式下,使用 `cancellation_policy: abandon` 调度的活动会继续运行。终止事件会在 `abandoned_activities` 中列出它,其结果永远不会记录到已关闭的运行上。子工作流遵循其父关闭策略。 + ## 嵌套屏障 {#nested-barriers} 嵌套 `all([...])` 组让一个工作流步骤表达持久扇出与扇入工作树。运行时将每个活动或子工作流调度为持久叶序列,记录叶的完整 `parallel_group_path`,等待所有包围屏障可推进,然后重建原始嵌套结果结构,再恢复工作流主体。重放时,`all([...])` 步骤中的活动或子叶仍须匹配已记录组路径;缺少组元数据的类型化叶历史会被视为不兼容的旧预览版历史,不会被推测纳入当前屏障。 diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/continue-as-new.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/continue-as-new.md index 985700d7b85..1373a6d80ee 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/continue-as-new.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/continue-as-new.md @@ -66,6 +66,8 @@ Core 2.7.0 和兼容 Server 会保留已收到、由运行命令契约声明处 长期运行的循环可以释放历史,无需在每次运行推进时创建新的公开工作流 ID。 +从 Workflow 2.28 起,正在关闭的运行从未等待的活动和计时器会在 continue-as-new 时被取消;子工作流则会移交给继续后的运行。参见[运行关闭时的落选成员](./concurrency.md#selection-losers-at-close)。 + ## 历史预算 {#history-budget} 工作流代码可通过显式运行时上下文读取当前历史长度和继续为新运行的建议标记,让长期循环在触及历史预算边界之前主动交接。 diff --git a/i18n/zh-Hans/source-hashes.json b/i18n/zh-Hans/source-hashes.json index 3f24f58ae53..fb4faa26280 100644 --- a/i18n/zh-Hans/source-hashes.json +++ b/i18n/zh-Hans/source-hashes.json @@ -4,7 +4,7 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", + "compatibility.md": "d2e8f2add0f4e59823adbe8245bf8befa4820bc4ea51cbc96a0a07d62256cde6", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", @@ -33,9 +33,9 @@ "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", - "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", + "features/concurrency.md": "c6c10761dc0cd1bb167a385d4237412b8e81589e380a1b4f0d21ee4f03f74e76", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", - "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", + "features/continue-as-new.md": "63b6ac32d5371a57d48cca7594a93e73d3f24394fba18d8a808eefe6eff017fb", "features/events.md": "c466df05908748489226a3d1410c9203cf6f2986a4bb7539db1c5f82715abc7b", "features/external-payload-storage.md": "acc312fa2f50a43c96e1d235439124d28a7048f0bf3abac34319467fcbf7e898", "features/heartbeats.md": "4fce9636d68c89f29f259d52e463cd67eccf0bc55ad4d53338ed03329892b365", diff --git a/static/stable-releases.json b/static/stable-releases.json index 2ec4acd68ca..ff4ae006245 100644 --- a/static/stable-releases.json +++ b/static/stable-releases.json @@ -10,7 +10,7 @@ "sdk-rust": "4.14.0", "server": "3.8.0", "waterline": "2.17.0", - "workflow": "2.27.0" + "workflow": "2.28.0" }, "helm_chart": { "app_version": "3.8.0",