diff --git a/docs/compatibility.md b/docs/compatibility.md index 8267d3ac0c6..9fd4e02308b 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.26 | PHP 8.2+ in 8.x; PHP 8.3+ for Laravel 13 | `^12.69.0` or `^13.30.0` | +| Current embedded Workflow 2.27 | 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.26.0/resources/laravel-embedded-upgrade-contract.json) +The [published embedded upgrade contract](https://github.com/durable-workflow/workflow/blob/2.27.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 @@ -193,6 +193,13 @@ See the release notes for [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0) and [2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0). +Workflow 2.27 keeps the 2.21 support floors and the embedded worker protocol `1.22`, and adds no database migration. Changes to check before upgrading: + +- From 2.27, an embedded app repairs and runs work only in its own namespaces. If the app starts, schedules or signals workflows in namespaces other than `DW_V2_NAMESPACE`, list them all in `DW_V2_NAMESPACES`. A process that serves every namespace sets `DW_V2_ALL_NAMESPACES=true`. See [Which namespaces an app runs](./configuration/options.md#namespace-allowlist). +- From 2.27, closing a child costs the parent the same work however many siblings it has. See [Cost of wide fan-out](./features/child-workflows.md#fan-out-cost). + +See the [2.27.0 release notes](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). + ## Stability Levels Every public surface in Durable Workflow carries exactly one of these diff --git a/docs/configuration/options.md b/docs/configuration/options.md index 1dad7b539d7..5cf6b38b504 100644 --- a/docs/configuration/options.md +++ b/docs/configuration/options.md @@ -167,6 +167,21 @@ $controlPlane->start('order-processing', 'order-12345', [ When no namespace is configured and none is passed explicitly, new instances retain a `null` namespace. A namespace-scoped observer does not include those runs. Changing configuration does not reassign existing instances. Starting an existing instance through a different namespace is rejected. +### Which namespaces an app runs {#namespace-allowlist} + +From Workflow 2.27, an embedded app repairs and runs work only in the namespaces it serves. This covers the watchdog, task repair, run and activity deadlines, `workflow:v2:schedule-tick`, and the queued workflow, activity, timer and service-call jobs. A queued job for another namespace is skipped before it has any effect, and a warning is logged. + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- When `DW_V2_NAMESPACES` is unset, the app serves exactly `DW_V2_NAMESPACE`, so a single-namespace app needs no change. +- When it is set, the app serves exactly the listed namespaces, so include `DW_V2_NAMESPACE` itself. `default` names the unscoped namespace. An empty value serves none, and `*` is refused. +- A process that repairs or ticks every namespace in the database, such as a standalone server, sets `DW_V2_ALL_NAMESPACES=true` instead. + +List every namespace the app starts, schedules or signals workflows in. Otherwise their tasks and schedules wait for an app that serves them. The allowlist keeps one app from running another app's work with the wrong code or credentials. It isn't tenant isolation: apps that share a database can still read each other's rows. Refused work is counted in `namespace_scope_refusals`; see [Monitoring](../monitoring.md#stuck-run-metrics). + ### Waterline namespace scoping When Waterline is deployed against a shared database with multiple namespaces, set `WATERLINE_NAMESPACE` to restrict all list views to one namespace: diff --git a/docs/features/child-workflows.md b/docs/features/child-workflows.md index c4727627aac..2084e5838e9 100644 --- a/docs/features/child-workflows.md +++ b/docs/features/child-workflows.md @@ -81,6 +81,17 @@ That child-only form is still useful when every parallel member is a child workf If you need to combine child workflows with activities in the same fan-in step, use one mixed `all([...])` barrier instead. The child waits and activity waits share the same `parallel_group_id`, and Waterline labels that shared barrier as `parallel_group_kind = mixed`. If one mixed or child-only subgroup sits inside a larger `all([...])`, the innermost group still drives `parallel_group_id` while `parallel_group_path` preserves the full outer-to-inner path. +### Cost of wide fan-out {#fan-out-cost} + +Each child close locks the parent run while it records the child's outcome, checks the group barrier and updates the parent's projections. In Workflow 2.27 and later, that work doesn't grow with the number of siblings: a close reads no other child's history and runs a fixed number of queries. Closes of one parent's children still take turns on the parent's lock, and the parent can't run its own workflow task while a close holds it. + +Before 2.27, each close also re-read every sibling's history and run, so closing all children of a wide fan-out cost work that grew with the square of the number of children. + +For fan-outs in the hundreds, or close to the default limit of 1,000 pending children (`pending_child_count`, see [Structural limits](../constraints/structural-limits.md)), split the work: + +- **Batches:** start a group of children, wait for it with `all([...])`, then start the next group. +- **A tree:** let each child start its own children, so no single parent supervises more than a few hundred at once. + ## Identity Contract - `child()->id()` and Waterline `target_name` refer to the child workflow instance id, which stays stable across that child instance's run chain. diff --git a/docs/monitoring.md b/docs/monitoring.md index d3f9a72944c..577708fc34c 100644 --- a/docs/monitoring.md +++ b/docs/monitoring.md @@ -161,7 +161,7 @@ Runs with workflow-task trouble have `task_problem = true`. Filter run lists on - `active` (Task Problem): workflow-task work is missing, retrying or cannot be delivered right now. - `history` (Task History): the run needed workflow-task repair or replay recovery earlier. -### Metrics and health +### Metrics and health {#stuck-run-metrics} Embedded operator metrics (`operator_metrics` in Waterline stats) count open runs in each problem state. Closed runs are not counted. @@ -175,6 +175,8 @@ The advisory `replay_blocked_runs` health check (category `correctness`) reports Native Server reports `replay_blocked` and the `replay_blocked_runs` check from 3.6.0. +From Workflow 2.27, `operator_metrics.namespace_scope_refusals` counts work the app's [namespace allowlist](./configuration/options.md#namespace-allowlist) refused in the last 15 minutes, by namespace and path. `job` counts skipped queued jobs. `repair`, `timeout` and `schedule_tick` count repair candidates, expired deadlines and due schedules left in a namespace outside the allowlist for more than two minutes. The advisory `namespace_scope_refusals` health check warns while refusals keep arriving and clears 15 minutes after the last one. The counts live in the default cache store, so use a shared store (Redis, database or Memcached) so that the web process serving health sees the workers' counts. + ### Server workflow-task failures Server reports failed workflow tasks in `GET /api/system/metrics` under `metrics.dw_workflow_task_consecutive_failures`: diff --git a/i18n/de/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/de/docusaurus-plugin-content-docs/current/compatibility.md index edd8a1cc8a1..743cb892e95 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.26 | PHP 8.2+ in 8.x; PHP 8.3+ für Laravel 13 | `^12.69.0` oder `^13.30.0` | +| 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` | | 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.26.0/resources/laravel-embedded-upgrade-contract.json) +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) 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/) @@ -124,6 +124,13 @@ Workflow 2.25 und 2.26 behalten die Mindestanforderungen von 2.21 und das eingeb Siehe die Versionshinweise zu [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0) und [2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0). +Workflow 2.27 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 Änderungen: + +- Ab 2.27 repariert und führt eine eingebettete App Arbeit nur in ihren eigenen Namespaces aus. Startet, plant oder signalisiert die App Workflows in anderen Namespaces als `DW_V2_NAMESPACE`, führen Sie alle in `DW_V2_NAMESPACES` auf. Ein Prozess, der jeden Namespace bedient, setzt `DW_V2_ALL_NAMESPACES=true`. Siehe [Welche Namespaces eine App ausführt](./configuration/options.md#namespace-allowlist). +- Ab 2.27 kostet der Abschluss eines Kindes den Elternworkflow gleich viel Arbeit, egal wie viele Geschwister es gibt. Siehe [Kosten breiter Verzweigungen](./features/child-workflows.md#fan-out-cost). + +Siehe die [Versionshinweise zu 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.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/configuration/options.md b/i18n/de/docusaurus-plugin-content-docs/current/configuration/options.md index fce5b8c53e7..bdd555a4ed4 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/configuration/options.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/configuration/options.md @@ -224,6 +224,21 @@ Beobachter schließt diese Ausführungen nicht ein. Konfigurationsänderungen weisen vorhandene Instanzen nicht neu zu. Der Start einer vorhandenen Instanz über einen anderen Namespace wird abgelehnt. +### Welche Namespaces eine App ausführt {#namespace-allowlist} + +Ab Workflow 2.27 repariert und führt eine eingebettete App Arbeit nur in den Namespaces aus, die sie bedient. Das betrifft den Watchdog, die Task-Reparatur, Lauf- und Aktivitätsfristen, `workflow:v2:schedule-tick` sowie die eingereihten Workflow-, Aktivitäts-, Timer- und Service-Call-Jobs. Ein eingereihter Job für einen anderen Namespace wird übersprungen, bevor er etwas bewirkt, und eine Warnung wird protokolliert. + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- Ist `DW_V2_NAMESPACES` nicht gesetzt, bedient die App genau `DW_V2_NAMESPACE`. Eine App mit einem einzigen Namespace muss also nichts ändern. +- Ist die Variable gesetzt, bedient die App genau die aufgeführten Namespaces. Nehmen Sie daher auch `DW_V2_NAMESPACE` selbst auf. `default` bezeichnet den Namespace ohne Zuordnung. Ein leerer Wert bedient keinen, und `*` wird abgelehnt. +- Ein Prozess, der jeden Namespace der Datenbank repariert oder tickt, etwa ein eigenständiger Server, setzt stattdessen `DW_V2_ALL_NAMESPACES=true`. + +Führen Sie jeden Namespace auf, in dem die App Workflows startet, plant oder signalisiert. Andernfalls warten deren Tasks und Zeitpläne auf eine App, die sie bedient. Die Allowlist verhindert, dass eine App die Arbeit einer anderen mit falschem Code oder falschen Zugangsdaten ausführt. Sie ist keine Mandantenisolation: Apps, die sich eine Datenbank teilen, können weiterhin die Zeilen der anderen lesen. Abgelehnte Arbeit wird in `namespace_scope_refusals` gezählt, siehe [Monitoring](../monitoring.md#stuck-run-metrics). + ### Namespace-Beschränkung in Waterline {#waterline-namespace-scoping} Wenn Waterline auf einer gemeinsamen Datenbank mit mehreren Namespaces diff --git a/i18n/de/docusaurus-plugin-content-docs/current/features/child-workflows.md b/i18n/de/docusaurus-plugin-content-docs/current/features/child-workflows.md index e02f0faf42d..8ee70e0b0f1 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/features/child-workflows.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/features/child-workflows.md @@ -97,6 +97,17 @@ in einer größeren `all([...])`-Gruppe, bestimmt weiterhin die innerste Gruppe die `parallel_group_id`. `parallel_group_path` erhält den vollständigen Pfad von außen nach innen. +### Kosten breiter Verzweigungen {#fan-out-cost} + +Jeder Abschluss eines Kindes sperrt den Elternlauf, während er das Ergebnis des Kindes aufzeichnet, die Gruppenbarriere prüft und die Projektionen des Elternworkflows aktualisiert. Ab Workflow 2.27 wächst dieser Aufwand nicht mehr mit der Zahl der Geschwister: Ein Abschluss liest die Historie keines anderen Kindes und führt eine feste Zahl von Abfragen aus. Abschlüsse der Kinder eines Elternworkflows warten weiterhin nacheinander auf dessen Sperre, und der Elternworkflow kann seinen eigenen Workflow-Task nicht ausführen, solange ein Abschluss sie hält. + +Vor 2.27 las jeder Abschluss zusätzlich die Historie und den Lauf jedes Geschwisters erneut. Alle Kinder einer breiten Verzweigung abzuschließen kostete daher Arbeit, die mit dem Quadrat der Kinderzahl wuchs. + +Bei Verzweigungen in die Hunderte oder nahe am Standardlimit von 1.000 ausstehenden Kindern (`pending_child_count`, siehe [Strukturelle Grenzen](../constraints/structural-limits.md)) teilen Sie die Arbeit auf: + +- **Stapel:** Starten Sie eine Gruppe von Kindern, warten Sie mit `all([...])` auf sie und starten Sie dann die nächste Gruppe. +- **Ein Baum:** Lassen Sie jedes Kind eigene Kinder starten, sodass kein einzelner Elternworkflow mehr als einige Hundert gleichzeitig beaufsichtigt. + ## Identitätsvertrag {#identity-contract} - `child()->id()` und Waterlines `target_name` beziehen sich auf die Workflow-Instanz-ID des Kindes, die über dessen Laufkette hinweg stabil bleibt. diff --git a/i18n/de/docusaurus-plugin-content-docs/current/monitoring.md b/i18n/de/docusaurus-plugin-content-docs/current/monitoring.md index 98e0129a053..d735a13df34 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/monitoring.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/monitoring.md @@ -136,6 +136,8 @@ Die beratende Health-Prüfung `replay_blocked_runs` (Kategorie `correctness`) me Der native Server meldet `replay_blocked` und die Prüfung `replay_blocked_runs` ab 3.6.0. +Ab Workflow 2.27 zählt `operator_metrics.namespace_scope_refusals` die Arbeit, die die [Namespace-Allowlist](./configuration/options.md#namespace-allowlist) der App in den letzten 15 Minuten abgelehnt hat, nach Namespace und Pfad. `job` zählt übersprungene eingereihte Jobs. `repair`, `timeout` und `schedule_tick` zählen Reparaturkandidaten, abgelaufene Fristen und fällige Zeitpläne, die länger als zwei Minuten in einem Namespace außerhalb der Allowlist liegen geblieben sind. Die beratende Health-Prüfung `namespace_scope_refusals` warnt, solange weiter Ablehnungen eintreffen, und wird 15 Minuten nach der letzten zurückgesetzt. Die Zähler liegen im Standard-Cache-Store. Verwenden Sie daher einen gemeinsamen Store (Redis, Datenbank oder Memcached), damit der Webprozess, der den Health-Status liefert, die Zähler der Worker sieht. + ### Fehlgeschlagene Workflow-Tasks im Server {#workflow-task-failure-metric} Der Server meldet fehlgeschlagene Workflow-Tasks in `GET /api/system/metrics` unter `metrics.dw_workflow_task_consecutive_failures`: diff --git a/i18n/de/source-hashes.json b/i18n/de/source-hashes.json index 0cbd7a72844..3f24f58ae53 100644 --- a/i18n/de/source-hashes.json +++ b/i18n/de/source-hashes.json @@ -4,12 +4,12 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "ad5c8519be03ae1e7b6e5e03b05a886862fd67c603b241ecb5baf2be5cd59610", + "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", "configuration/microservices.md": "46dc4afa07588b78829a7e3d259177ce0cf40861f0e31b88dbb6de3a83aa5488", - "configuration/options.md": "6a55ce6dd9828ad20a024d8d495b254bf1e1eea51dda3abd51ef4008e1dc9e9d", + "configuration/options.md": "42c40c50ecdf9fc6eace79d212229dfe0dac119c23137225f0ce353952fbd549", "configuration/pruning-workflows.md": "6f6ee2be3bd185ffec764e86c3ed3cbd40c45f75d28671b4cd11226493e11afb", "configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6", "constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05", @@ -32,7 +32,7 @@ "failures-and-recovery.md": "a240727af9539cca9cceb6ab3ddea545c95f21402813365442929ea05c09e70c", "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", - "features/child-workflows.md": "278b634b8b48b94203309cdba27d6116897a2919cab19628add8cd85dadb08d3", + "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", @@ -63,7 +63,7 @@ "laravel-adoption.md": "be0890619736ee2362ee96b6b1f5f397f10fb58cb845448ac15b437ac3062b36", "mcp-workflows.md": "1c0b5bb7f2e5c7ca835dfdfa57bbe8f6624172c855f4e225057ac2377abf360e", "migration.md": "7304a53786d5e45d3a639c33386e6558e855ee77982883a5e051ef5084b8453b", - "monitoring.md": "afbf43eacdd7ab017c75478a5ee4cb08745f7e4513799f949e57fc7f4d0fec2a", + "monitoring.md": "346b8a5207b7d69cea63dc9bfec95bf1911d3038a9d30ad06939b13130079279", "operator-operating-envelope.md": "dc0cf13d8593e4ce2d8ec1912e45e61c9bf13f06abf7cc8c422379db5e3fa0ad", "platform-conformance.md": "2eec7eba9a65c010e03c4b2eb78afe4dddd6fd8170218b3194c49e3777124c91", "platform-protocol-specs.md": "ba9c69adfca7fb4a0dd982464b0ca69dd5a21de1e340edbe23b075ec0fb0c35c", diff --git a/i18n/es/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/es/docusaurus-plugin-content-docs/current/compatibility.md index 090a506cc6f..0b7161ef913 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.26 actual | PHP 8.2+ de 8.x; PHP 8.3+ para Laravel 13 | `^12.69.0` o `^13.30.0` | +| 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.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.26.0/resources/laravel-embedded-upgrade-contract.json) +Las autoridades son el [contrato integrado publicado](https://github.com/durable-workflow/workflow/blob/2.27.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/) @@ -157,6 +157,13 @@ Workflow 2.25 y 2.26 mantienen los mínimos de soporte de 2.21 y el protocolo de Consulte las notas de versión de [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0) y [2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0). +Workflow 2.27 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. Cambios que conviene revisar antes de actualizar: + +- Desde 2.27, una aplicación integrada repara y ejecuta trabajo solo en sus propios espacios de nombres. Si la aplicación inicia, programa o envía señales a workflows en espacios de nombres distintos de `DW_V2_NAMESPACE`, inclúyalos todos en `DW_V2_NAMESPACES`. Un proceso que atiende todos los espacios de nombres define `DW_V2_ALL_NAMESPACES=true`. Consulte [Qué espacios de nombres ejecuta una aplicación](./configuration/options.md#namespace-allowlist). +- Desde 2.27, cerrar un hijo le cuesta al padre el mismo trabajo sin importar cuántos hermanos tenga. Consulte [Coste de una ramificación amplia](./features/child-workflows.md#fan-out-cost). + +Consulte las [notas de la versión 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.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/configuration/options.md b/i18n/es/docusaurus-plugin-content-docs/current/configuration/options.md index e549ce95681..df078aa624c 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/configuration/options.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/configuration/options.md @@ -167,6 +167,21 @@ $controlPlane->start('order-processing', 'order-12345', [ Si no se configura ni se pasa explícitamente un espacio, las nuevas instancias conservan `null`. Un observador limitado a un espacio no incluye esas ejecuciones. Cambiar la configuración no reasigna las instancias existentes. Se rechaza iniciar una instancia existente mediante otro espacio. +### Qué espacios de nombres ejecuta una aplicación {#namespace-allowlist} + +Desde Workflow 2.27, una aplicación integrada repara y ejecuta trabajo solo en los espacios de nombres que atiende. Esto abarca el watchdog, la reparación de tareas, los plazos de ejecuciones y actividades, `workflow:v2:schedule-tick` y los jobs en cola de workflows, actividades, temporizadores y llamadas a servicios. Un job en cola de otro espacio de nombres se omite antes de tener ningún efecto y se registra una advertencia. + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- Si `DW_V2_NAMESPACES` no está definido, la aplicación atiende exactamente `DW_V2_NAMESPACE`, así que una aplicación con un solo espacio de nombres no necesita cambios. +- Si está definido, la aplicación atiende exactamente los espacios de nombres de la lista, así que incluya también `DW_V2_NAMESPACE`. `default` designa el espacio de nombres sin asignar. Un valor vacío no atiende ninguno y `*` se rechaza. +- Un proceso que repara o ejecuta el tick de todos los espacios de nombres de la base de datos, como un servidor independiente, define `DW_V2_ALL_NAMESPACES=true` en su lugar. + +Incluya cada espacio de nombres en el que la aplicación inicia, programa o envía señales a workflows. De lo contrario, sus tareas y programaciones esperan a una aplicación que los atienda. La lista de permitidos evita que una aplicación ejecute el trabajo de otra con el código o las credenciales equivocados. No es aislamiento de inquilinos: las aplicaciones que comparten una base de datos aún pueden leer las filas de las demás. El trabajo rechazado se cuenta en `namespace_scope_refusals`; consulte [Monitorización](../monitoring.md#stuck-run-metrics). + ### Limitar Waterline a un espacio de nombres {#waterline-namespace-scoping} Si Waterline usa una base de datos compartida con varios espacios, establece `WATERLINE_NAMESPACE` para restringir todas las listas a uno: diff --git a/i18n/es/docusaurus-plugin-content-docs/current/features/child-workflows.md b/i18n/es/docusaurus-plugin-content-docs/current/features/child-workflows.md index 0e7261a6f3a..190595e1df7 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/features/child-workflows.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/features/child-workflows.md @@ -78,6 +78,17 @@ La forma exclusiva de hijos sigue siendo útil cuando todos los miembros paralel Para combinar hijos y actividades en el mismo paso de reunión, usa una barrera mixta `all([...])`. Las esperas comparten `parallel_group_id` y Waterline la etiqueta `parallel_group_kind = mixed`. Si un subgrupo mixto o de hijos está dentro de otro `all([...])`, el grupo más interno determina `parallel_group_id` y `parallel_group_path` conserva la ruta completa de fuera hacia dentro. +### Coste de una ramificación amplia {#fan-out-cost} + +Cada cierre de un hijo bloquea la ejecución padre mientras registra el resultado del hijo, comprueba la barrera del grupo y actualiza las proyecciones del padre. Desde Workflow 2.27, ese trabajo ya no crece con el número de hermanos: un cierre no lee el historial de ningún otro hijo y ejecuta un número fijo de consultas. Los cierres de los hijos de un mismo padre siguen turnándose en el bloqueo del padre, y el padre no puede ejecutar su propia tarea de workflow mientras un cierre lo mantiene. + +Antes de 2.27, cada cierre también volvía a leer el historial y la ejecución de cada hermano, así que cerrar todos los hijos de una ramificación amplia costaba un trabajo que crecía con el cuadrado del número de hijos. + +Para ramificaciones de cientos de hijos, o cercanas al límite predeterminado de 1000 hijos pendientes (`pending_child_count`, consulta [Límites estructurales](../constraints/structural-limits.md)), divide el trabajo: + +- **Lotes:** inicia un grupo de hijos, espéralo con `all([...])` y luego inicia el siguiente grupo. +- **Un árbol:** deja que cada hijo inicie sus propios hijos, para que ningún padre supervise más de unos cientos a la vez. + ## Contrato de identidad {#identity-contract} - `child()->id()` y `target_name` en Waterline son el id de instancia del hijo, estable a lo largo de su cadena de ejecuciones. diff --git a/i18n/es/docusaurus-plugin-content-docs/current/monitoring.md b/i18n/es/docusaurus-plugin-content-docs/current/monitoring.md index 952a1934da1..819a2030d45 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/monitoring.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/monitoring.md @@ -172,6 +172,8 @@ La comprobación de salud informativa `replay_blocked_runs` (categoría `correct El Server nativo informa `replay_blocked` y la comprobación `replay_blocked_runs` desde la 3.6.0. +Desde Workflow 2.27, `operator_metrics.namespace_scope_refusals` cuenta el trabajo que la [lista de espacios de nombres permitidos](./configuration/options.md#namespace-allowlist) de la aplicación rechazó en los últimos 15 minutos, por espacio de nombres y por ruta. `job` cuenta los jobs en cola omitidos. `repair`, `timeout` y `schedule_tick` cuentan candidatos a reparación, plazos vencidos y programaciones pendientes que quedaron más de dos minutos en un espacio de nombres fuera de la lista. La comprobación de salud consultiva `namespace_scope_refusals` avisa mientras sigan llegando rechazos y se borra 15 minutos después del último. Los contadores se guardan en el almacén de caché predeterminado, así que use un almacén compartido (Redis, base de datos o Memcached) para que el proceso web que sirve la salud vea los contadores de los workers. + ### Fallos de tareas de workflow en Server {#workflow-task-failure-metric} Server informa de las tareas de workflow fallidas en `GET /api/system/metrics`, bajo `metrics.dw_workflow_task_consecutive_failures`: diff --git a/i18n/es/source-hashes.json b/i18n/es/source-hashes.json index 0cbd7a72844..3f24f58ae53 100644 --- a/i18n/es/source-hashes.json +++ b/i18n/es/source-hashes.json @@ -4,12 +4,12 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "ad5c8519be03ae1e7b6e5e03b05a886862fd67c603b241ecb5baf2be5cd59610", + "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", "configuration/microservices.md": "46dc4afa07588b78829a7e3d259177ce0cf40861f0e31b88dbb6de3a83aa5488", - "configuration/options.md": "6a55ce6dd9828ad20a024d8d495b254bf1e1eea51dda3abd51ef4008e1dc9e9d", + "configuration/options.md": "42c40c50ecdf9fc6eace79d212229dfe0dac119c23137225f0ce353952fbd549", "configuration/pruning-workflows.md": "6f6ee2be3bd185ffec764e86c3ed3cbd40c45f75d28671b4cd11226493e11afb", "configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6", "constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05", @@ -32,7 +32,7 @@ "failures-and-recovery.md": "a240727af9539cca9cceb6ab3ddea545c95f21402813365442929ea05c09e70c", "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", - "features/child-workflows.md": "278b634b8b48b94203309cdba27d6116897a2919cab19628add8cd85dadb08d3", + "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", @@ -63,7 +63,7 @@ "laravel-adoption.md": "be0890619736ee2362ee96b6b1f5f397f10fb58cb845448ac15b437ac3062b36", "mcp-workflows.md": "1c0b5bb7f2e5c7ca835dfdfa57bbe8f6624172c855f4e225057ac2377abf360e", "migration.md": "7304a53786d5e45d3a639c33386e6558e855ee77982883a5e051ef5084b8453b", - "monitoring.md": "afbf43eacdd7ab017c75478a5ee4cb08745f7e4513799f949e57fc7f4d0fec2a", + "monitoring.md": "346b8a5207b7d69cea63dc9bfec95bf1911d3038a9d30ad06939b13130079279", "operator-operating-envelope.md": "dc0cf13d8593e4ce2d8ec1912e45e61c9bf13f06abf7cc8c422379db5e3fa0ad", "platform-conformance.md": "2eec7eba9a65c010e03c4b2eb78afe4dddd6fd8170218b3194c49e3777124c91", "platform-protocol-specs.md": "ba9c69adfca7fb4a0dd982464b0ca69dd5a21de1e340edbe23b075ec0fb0c35c", diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/fr/docusaurus-plugin-content-docs/current/compatibility.md index cc538f0fd87..0b294c641ea 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.26 actuel | PHP 8.2+ en 8.x ; PHP 8.3+ pour Laravel 13 | `^12.69.0` ou `^13.30.0` | +| 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.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.26.0/resources/laravel-embedded-upgrade-contract.json) +Le [contrat embarqué publié](https://github.com/durable-workflow/workflow/blob/2.27.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/) @@ -153,6 +153,13 @@ Workflow 2.25 et 2.26 conservent les planchers de support de 2.21 et le protocol Voir les notes de version de [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0) et [2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0). +Workflow 2.27 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. Changements à vérifier avant la mise à niveau : + +- Depuis 2.27, une application embarquée ne répare et n'exécute le travail que dans ses propres espaces de noms. Si l'application démarre, planifie ou signale des workflows dans d'autres espaces de noms que `DW_V2_NAMESPACE`, listez-les tous dans `DW_V2_NAMESPACES`. Un processus qui sert tous les espaces de noms définit `DW_V2_ALL_NAMESPACES=true`. Voir [Espaces de noms exécutés par une application](./configuration/options.md#namespace-allowlist). +- Depuis 2.27, la clôture d'un enfant coûte au parent le même travail, quel que soit le nombre de ses frères et sœurs. Voir [Coût d’un large éventail d’enfants](./features/child-workflows.md#fan-out-cost). + +Voir les [notes de version de 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.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/configuration/options.md b/i18n/fr/docusaurus-plugin-content-docs/current/configuration/options.md index d6281f03979..7d1f71bfd55 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/configuration/options.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/configuration/options.md @@ -167,6 +167,21 @@ $controlPlane->start('order-processing', 'order-12345', [ Lorsqu’aucun espace de noms n’est configuré ni transmis explicitement, les nouvelles instances conservent un espace de noms `null`. Un observateur limité à un espace de noms n’inclut pas ces exécutions. Modifier la configuration ne réaffecte pas les instances existantes. Le démarrage d’une instance existante via un autre espace de noms est rejeté. +### Espaces de noms exécutés par une application {#namespace-allowlist} + +Depuis Workflow 2.27, une application embarquée ne répare et n’exécute le travail que dans les espaces de noms qu’elle sert. Cela concerne le watchdog, la réparation des tâches, les échéances des exécutions et des activités, `workflow:v2:schedule-tick`, ainsi que les jobs en file de workflows, d’activités, de minuteurs et d’appels de service. Un job en file destiné à un autre espace de noms est ignoré avant d’avoir le moindre effet, et un avertissement est journalisé. + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- Si `DW_V2_NAMESPACES` n’est pas défini, l’application sert exactement `DW_V2_NAMESPACE` : une application à un seul espace de noms n’a rien à changer. +- S’il est défini, l’application sert exactement les espaces de noms listés : incluez donc aussi `DW_V2_NAMESPACE`. `default` désigne l’espace de noms non attribué. Une valeur vide n’en sert aucun, et `*` est refusé. +- Un processus qui répare ou exécute le tick de tous les espaces de noms de la base, comme un serveur autonome, définit plutôt `DW_V2_ALL_NAMESPACES=true`. + +Listez chaque espace de noms dans lequel l’application démarre, planifie ou signale des workflows. Sinon, leurs tâches et planifications attendent une application qui les sert. La liste d’autorisation empêche une application d’exécuter le travail d’une autre avec le mauvais code ou les mauvais identifiants. Ce n’est pas une isolation des locataires : des applications qui partagent une base peuvent toujours lire les lignes des autres. Le travail refusé est compté dans `namespace_scope_refusals` ; voir [Supervision](../monitoring.md#stuck-run-metrics). + ### Portée de l’espace de noms dans Waterline {#waterline-namespace-scoping} Lorsque Waterline utilise une base partagée avec plusieurs espaces de noms, définissez `WATERLINE_NAMESPACE` pour limiter toutes les listes à un seul espace : diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/features/child-workflows.md b/i18n/fr/docusaurus-plugin-content-docs/current/features/child-workflows.md index 9106a5ccfac..07205d32076 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/features/child-workflows.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/features/child-workflows.md @@ -78,6 +78,17 @@ Cette forme réservée aux enfants est utile si chaque membre parallèle est un Pour combiner workflows enfants et activités dans une même étape de regroupement, utilisez une barrière `all([...])` mixte. Les attentes d’enfants et d’activités partagent le même `parallel_group_id`, et Waterline indique `parallel_group_kind = mixed`. Si un sous-groupe mixte ou réservé aux enfants est imbriqué dans un `all([...])` plus grand, le groupe le plus interne détermine toujours `parallel_group_id`, tandis que `parallel_group_path` conserve le chemin complet de l’extérieur vers l’intérieur. +### Coût d’un large éventail d’enfants {#fan-out-cost} + +Chaque clôture d’un enfant verrouille l’exécution parente pendant qu’elle enregistre le résultat de l’enfant, vérifie la barrière du groupe et met à jour les projections du parent. Depuis Workflow 2.27, ce travail ne croît plus avec le nombre de frères et sœurs : une clôture ne lit l’historique d’aucun autre enfant et exécute un nombre fixe de requêtes. Les clôtures des enfants d’un même parent passent toujours chacune leur tour sur le verrou du parent, et le parent ne peut pas exécuter sa propre tâche de workflow tant qu’une clôture le détient. + +Avant 2.27, chaque clôture relisait aussi l’historique et l’exécution de chaque frère ou sœur. Clôturer tous les enfants d’un large éventail coûtait donc un travail qui croissait avec le carré du nombre d’enfants. + +Pour des éventails de plusieurs centaines d’enfants, ou proches de la limite par défaut de 1 000 enfants en attente (`pending_child_count`, voir [Limites structurelles](../constraints/structural-limits.md)), découpez le travail : + +- **Lots :** démarrez un groupe d’enfants, attendez-le avec `all([...])`, puis démarrez le groupe suivant. +- **Un arbre :** laissez chaque enfant démarrer ses propres enfants, afin qu’aucun parent ne supervise plus de quelques centaines d’enfants à la fois. + ## Contrat d’identité {#identity-contract} - `child()->id()` et le `target_name` de Waterline désignent l’identifiant d’instance enfant, stable dans toute sa chaîne d’exécutions. diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/monitoring.md b/i18n/fr/docusaurus-plugin-content-docs/current/monitoring.md index b4550b3d89e..4df503b24dc 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/monitoring.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/monitoring.md @@ -175,6 +175,8 @@ La vérification de santé consultative `replay_blocked_runs` (catégorie `corre Le Server natif signale `replay_blocked` et la vérification `replay_blocked_runs` depuis la 3.6.0. +Depuis Workflow 2.27, `operator_metrics.namespace_scope_refusals` compte le travail que la [liste d’autorisation des espaces de noms](./configuration/options.md#namespace-allowlist) de l’application a refusé au cours des 15 dernières minutes, par espace de noms et par chemin. `job` compte les jobs en file ignorés. `repair`, `timeout` et `schedule_tick` comptent les candidats à la réparation, les échéances dépassées et les planifications dues restées plus de deux minutes dans un espace de noms hors de la liste. La vérification de santé consultative `namespace_scope_refusals` avertit tant que des refus arrivent et s’efface 15 minutes après le dernier. Les compteurs sont stockés dans le cache par défaut : utilisez un stockage partagé (Redis, base de données ou Memcached) pour que le processus web qui sert la santé voie les compteurs des workers. + ### Échecs de tâches de workflow côté Server {#workflow-task-failure-metric} Le Server signale les tâches de workflow en échec dans `GET /api/system/metrics`, sous `metrics.dw_workflow_task_consecutive_failures` : diff --git a/i18n/fr/source-hashes.json b/i18n/fr/source-hashes.json index 0cbd7a72844..3f24f58ae53 100644 --- a/i18n/fr/source-hashes.json +++ b/i18n/fr/source-hashes.json @@ -4,12 +4,12 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "ad5c8519be03ae1e7b6e5e03b05a886862fd67c603b241ecb5baf2be5cd59610", + "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", "configuration/microservices.md": "46dc4afa07588b78829a7e3d259177ce0cf40861f0e31b88dbb6de3a83aa5488", - "configuration/options.md": "6a55ce6dd9828ad20a024d8d495b254bf1e1eea51dda3abd51ef4008e1dc9e9d", + "configuration/options.md": "42c40c50ecdf9fc6eace79d212229dfe0dac119c23137225f0ce353952fbd549", "configuration/pruning-workflows.md": "6f6ee2be3bd185ffec764e86c3ed3cbd40c45f75d28671b4cd11226493e11afb", "configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6", "constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05", @@ -32,7 +32,7 @@ "failures-and-recovery.md": "a240727af9539cca9cceb6ab3ddea545c95f21402813365442929ea05c09e70c", "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", - "features/child-workflows.md": "278b634b8b48b94203309cdba27d6116897a2919cab19628add8cd85dadb08d3", + "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", @@ -63,7 +63,7 @@ "laravel-adoption.md": "be0890619736ee2362ee96b6b1f5f397f10fb58cb845448ac15b437ac3062b36", "mcp-workflows.md": "1c0b5bb7f2e5c7ca835dfdfa57bbe8f6624172c855f4e225057ac2377abf360e", "migration.md": "7304a53786d5e45d3a639c33386e6558e855ee77982883a5e051ef5084b8453b", - "monitoring.md": "afbf43eacdd7ab017c75478a5ee4cb08745f7e4513799f949e57fc7f4d0fec2a", + "monitoring.md": "346b8a5207b7d69cea63dc9bfec95bf1911d3038a9d30ad06939b13130079279", "operator-operating-envelope.md": "dc0cf13d8593e4ce2d8ec1912e45e61c9bf13f06abf7cc8c422379db5e3fa0ad", "platform-conformance.md": "2eec7eba9a65c010e03c4b2eb78afe4dddd6fd8170218b3194c49e3777124c91", "platform-protocol-specs.md": "ba9c69adfca7fb4a0dd982464b0ca69dd5a21de1e340edbe23b075ec0fb0c35c", diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/ja/docusaurus-plugin-content-docs/current/compatibility.md index de5e8265344..3adc4f4738a 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.26 | 8.x 系の PHP 8.2 以降。Laravel 13 は PHP 8.3 以降 | `^12.69.0` または `^13.30.0` | +| 現在の組み込み Workflow 2.27 | 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.26.0/resources/laravel-embedded-upgrade-contract.json) +[公開済み組み込みアップグレード契約](https://github.com/durable-workflow/workflow/blob/2.27.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 のサポートは終了しました。 @@ -120,6 +120,13 @@ Workflow 2.25 と 2.26 は 2.21 のサポート下限と組み込みワーカー [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0)、[2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0) のリリースノートを参照してください。 +Workflow 2.27 は 2.21 のサポート下限と組み込みワーカープロトコル `1.22` を維持し、データベースマイグレーションは追加しません。アップグレード前に確認すべき変更: + +- 2.27 以降、組み込みアプリは自身の名前空間の作業だけを修復・実行します。アプリが `DW_V2_NAMESPACE` 以外の名前空間でワークフローを開始、スケジュール、またはシグナル送信する場合は、それらをすべて `DW_V2_NAMESPACES` に列挙してください。すべての名前空間を担当するプロセスは `DW_V2_ALL_NAMESPACES=true` を設定します。[アプリが実行する名前空間](./configuration/options.md#namespace-allowlist)を参照してください。 +- 2.27 以降、子の完了処理が親に課す作業量は兄弟の数に関係なく一定です。[大規模なファンアウトのコスト](./features/child-workflows.md#fan-out-cost)を参照してください。 + +[2.27.0 のリリースノート](https://github.com/durable-workflow/workflow/releases/tag/2.27.0)を参照してください。 + ## 安定性レベル {#stability-levels} Durable Workflow の各公開インターフェースは、次の安定性レベルを厳密に一つ持ちます。分類は明示的です。未分類のインターフェースは公開ではありません。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/configuration/options.md b/i18n/ja/docusaurus-plugin-content-docs/current/configuration/options.md index f6e5eacaa10..55c1d2dc5ae 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/configuration/options.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/configuration/options.md @@ -167,6 +167,21 @@ $controlPlane->start('order-processing', 'order-12345', [ 設定にも明示的な指定にも名前空間がなければ、新しいインスタンスは `null` のままです。名前空間に限定した観測には、それらの実行は含まれません。設定を変更しても既存インスタンスは再割り当てされません。別の名前空間を通じた既存インスタンスの開始は拒否されます。 +### アプリが実行する名前空間 {#namespace-allowlist} + +Workflow 2.27 以降、組み込みアプリは自身が担当する名前空間の作業だけを修復・実行します。対象はウォッチドッグ、タスクの修復、実行とアクティビティの期限、`workflow:v2:schedule-tick`、およびキューに入ったワークフロー、アクティビティ、タイマー、サービス呼び出しのジョブです。別の名前空間のキュー済みジョブは何の効果も及ぼす前にスキップされ、警告がログに記録されます。 + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- `DW_V2_NAMESPACES` が未設定の場合、アプリは `DW_V2_NAMESPACE` だけを担当します。名前空間が 1 つのアプリは変更不要です。 +- 設定した場合、アプリは列挙した名前空間だけを担当するため、`DW_V2_NAMESPACE` 自体も含めてください。`default` は名前空間未指定を表します。空の値はどの名前空間も担当せず、`*` は拒否されます。 +- スタンドアロンサーバーのように、データベース内のすべての名前空間を修復または tick するプロセスは、代わりに `DW_V2_ALL_NAMESPACES=true` を設定します。 + +アプリがワークフローを開始、スケジュール、またはシグナル送信するすべての名前空間を列挙してください。そうしないと、それらのタスクとスケジュールは担当するアプリが現れるまで待機します。この許可リストは、あるアプリが別のアプリの作業を誤ったコードや認証情報で実行することを防ぎます。テナント分離ではありません。データベースを共有するアプリは引き続き互いの行を読み取れます。拒否された作業は `namespace_scope_refusals` に計上されます。[監視](../monitoring.md#stuck-run-metrics)を参照してください。 + ### Waterline の名前空間の限定 {#waterline-namespace-scoping} 複数の名前空間を持つ共有データベースに Waterline を配置する場合、`WATERLINE_NAMESPACE` で全一覧を1つの名前空間に制限します。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/features/child-workflows.md b/i18n/ja/docusaurus-plugin-content-docs/current/features/child-workflows.md index 4f85f53b339..e1190f1fc37 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/features/child-workflows.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/features/child-workflows.md @@ -78,6 +78,17 @@ final class ParentWorkflow extends Workflow 同じ fan-in にアクティビティも含むなら混合 `all([...])` を使います。両方の待機が `parallel_group_id` を共有し、Waterline は `parallel_group_kind = mixed` と表示します。より大きな `all([...])` に入れ子になっている場合、最内グループが ID を決め、`parallel_group_path` は外から内への全経路を保ちます。 +### 大規模なファンアウトのコスト {#fan-out-cost} + +子が完了するたびに、その処理は親の実行をロックしたまま、子の結果の記録、グループバリアの確認、親のプロジェクションの更新を行います。Workflow 2.27 以降では、この処理量は兄弟の数に応じて増えません。完了処理は他の子の履歴を読まず、一定数のクエリだけを実行します。ただし、同じ親の子の完了処理は親のロックを順番に取得し、完了処理がロックを保持している間、親は自身のワークフロータスクを実行できません。 + +2.27 より前は、完了のたびにすべての兄弟の履歴と実行も読み直していたため、大規模なファンアウトのすべての子を完了させる処理量は子の数の二乗に比例して増えていました。 + +数百の子へのファンアウトや、保留中の子の既定上限 1,000(`pending_child_count`、[構造上の制限](../constraints/structural-limits.md)を参照)に近い場合は、作業を分割してください。 + +- **バッチ:** 子のグループを開始し、`all([...])` で待ってから次のグループを開始します。 +- **ツリー:** 各子に自身の子を開始させ、1 つの親が同時に監督する子を数百以内に抑えます。 + ## 識別情報の契約 {#identity-contract} - `child()->id()` と Waterline の `target_name` は子のインスタンス ID で、子の実行連鎖を通して不変です。 diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/monitoring.md b/i18n/ja/docusaurus-plugin-content-docs/current/monitoring.md index 0bee87502e5..a5bf59e9c1c 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/monitoring.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/monitoring.md @@ -134,6 +134,8 @@ trace、run、activity、attempt、request の ID は別々です。baggage は ネイティブ Server は 3.6.0 から `replay_blocked` と `replay_blocked_runs` チェックを報告します。 +Workflow 2.27 以降、`operator_metrics.namespace_scope_refusals` は、アプリの[名前空間の許可リスト](./configuration/options.md#namespace-allowlist)が過去 15 分間に拒否した作業を名前空間とパスごとに数えます。`job` はスキップされたキュー済みジョブを数えます。`repair`、`timeout`、`schedule_tick` は、許可リスト外の名前空間に 2 分を超えて残った修復候補、期限切れ、実行予定のスケジュールを数えます。助言的なヘルスチェック `namespace_scope_refusals` は拒否が続く間は警告し、最後の拒否から 15 分後に解除されます。カウントは既定のキャッシュストアに保存されるため、ヘルスを返す Web プロセスがワーカーのカウントを参照できるよう、共有ストア(Redis、データベース、Memcached)を使用してください。 + ### Server のワークフロータスク失敗 {#workflow-task-failure-metric} Server は失敗したワークフロータスクを `GET /api/system/metrics` の `metrics.dw_workflow_task_consecutive_failures` で報告します。 diff --git a/i18n/ja/source-hashes.json b/i18n/ja/source-hashes.json index 0cbd7a72844..3f24f58ae53 100644 --- a/i18n/ja/source-hashes.json +++ b/i18n/ja/source-hashes.json @@ -4,12 +4,12 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "ad5c8519be03ae1e7b6e5e03b05a886862fd67c603b241ecb5baf2be5cd59610", + "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", "configuration/microservices.md": "46dc4afa07588b78829a7e3d259177ce0cf40861f0e31b88dbb6de3a83aa5488", - "configuration/options.md": "6a55ce6dd9828ad20a024d8d495b254bf1e1eea51dda3abd51ef4008e1dc9e9d", + "configuration/options.md": "42c40c50ecdf9fc6eace79d212229dfe0dac119c23137225f0ce353952fbd549", "configuration/pruning-workflows.md": "6f6ee2be3bd185ffec764e86c3ed3cbd40c45f75d28671b4cd11226493e11afb", "configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6", "constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05", @@ -32,7 +32,7 @@ "failures-and-recovery.md": "a240727af9539cca9cceb6ab3ddea545c95f21402813365442929ea05c09e70c", "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", - "features/child-workflows.md": "278b634b8b48b94203309cdba27d6116897a2919cab19628add8cd85dadb08d3", + "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", @@ -63,7 +63,7 @@ "laravel-adoption.md": "be0890619736ee2362ee96b6b1f5f397f10fb58cb845448ac15b437ac3062b36", "mcp-workflows.md": "1c0b5bb7f2e5c7ca835dfdfa57bbe8f6624172c855f4e225057ac2377abf360e", "migration.md": "7304a53786d5e45d3a639c33386e6558e855ee77982883a5e051ef5084b8453b", - "monitoring.md": "afbf43eacdd7ab017c75478a5ee4cb08745f7e4513799f949e57fc7f4d0fec2a", + "monitoring.md": "346b8a5207b7d69cea63dc9bfec95bf1911d3038a9d30ad06939b13130079279", "operator-operating-envelope.md": "dc0cf13d8593e4ce2d8ec1912e45e61c9bf13f06abf7cc8c422379db5e3fa0ad", "platform-conformance.md": "2eec7eba9a65c010e03c4b2eb78afe4dddd6fd8170218b3194c49e3777124c91", "platform-protocol-specs.md": "ba9c69adfca7fb4a0dd982464b0ca69dd5a21de1e340edbe23b075ec0fb0c35c", 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 a399280184f..2ad30878f0d 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.26 atual | PHP 8.2+ da linha 8.x; PHP 8.3+ para Laravel 13 | `^12.69.0` ou `^13.30.0` | +| 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.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.26.0/resources/laravel-embedded-upgrade-contract.json) +As autoridades são o [contrato embutido publicado](https://github.com/durable-workflow/workflow/blob/2.27.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/) @@ -157,6 +157,13 @@ O Workflow 2.25 e o 2.26 mantêm os pisos de suporte do 2.21 e o protocolo de wo Veja as notas de versão do [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0) e do [2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0). +O Workflow 2.27 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ças para verificar antes de atualizar: + +- A partir do 2.27, um app embutido repara e executa trabalho apenas em seus próprios namespaces. Se o app inicia, agenda ou sinaliza workflows em namespaces diferentes de `DW_V2_NAMESPACE`, liste todos em `DW_V2_NAMESPACES`. Um processo que atende todos os namespaces define `DW_V2_ALL_NAMESPACES=true`. Veja [Quais namespaces um app executa](./configuration/options.md#namespace-allowlist). +- A partir do 2.27, encerrar um filho custa ao pai o mesmo trabalho, não importa quantos irmãos ele tenha. Veja [Custo de uma ramificação ampla](./features/child-workflows.md#fan-out-cost). + +Veja as [notas da versão 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.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/configuration/options.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/configuration/options.md index 078ab933581..fe4604bd156 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/configuration/options.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/configuration/options.md @@ -167,6 +167,21 @@ $controlPlane->start('order-processing', 'order-12345', [ Quando nenhum namespace está configurado e nenhum é passado explicitamente, novas instâncias mantêm um namespace `null`. Um observador com escopo de namespace não inclui essas execuções. Alterar a configuração não reatribui instâncias existentes. Tentar iniciar uma instância existente por outro namespace é rejeitado. +### Quais namespaces um app executa {#namespace-allowlist} + +A partir do Workflow 2.27, um app embutido repara e executa trabalho apenas nos namespaces que atende. Isso inclui o watchdog, o reparo de tarefas, os prazos de execuções e atividades, `workflow:v2:schedule-tick` e os jobs enfileirados de workflows, atividades, timers e chamadas de serviço. Um job enfileirado de outro namespace é ignorado antes de ter qualquer efeito, e um aviso é registrado. + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- Quando `DW_V2_NAMESPACES` não está definido, o app atende exatamente `DW_V2_NAMESPACE`, então um app com um único namespace não precisa mudar nada. +- Quando está definido, o app atende exatamente os namespaces listados, então inclua também o próprio `DW_V2_NAMESPACE`. `default` designa o namespace sem escopo. Um valor vazio não atende nenhum, e `*` é recusado. +- Um processo que repara ou executa o tick de todos os namespaces do banco, como um servidor independente, define `DW_V2_ALL_NAMESPACES=true` em vez disso. + +Liste todos os namespaces em que o app inicia, agenda ou sinaliza workflows. Caso contrário, suas tarefas e agendamentos esperam por um app que os atenda. A lista de permissões impede que um app execute o trabalho de outro com o código ou as credenciais errados. Ela não é isolamento de inquilinos: apps que compartilham um banco ainda podem ler as linhas uns dos outros. O trabalho recusado é contado em `namespace_scope_refusals`; veja [Monitoramento](../monitoring.md#stuck-run-metrics). + ### Escopo de namespace no Waterline {#waterline-namespace-scoping} Quando o Waterline é implantado com um banco de dados compartilhado por múltiplos namespaces, defina `WATERLINE_NAMESPACE` para restringir todas as listagens a um namespace: diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/child-workflows.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/child-workflows.md index 1d359ba2fe6..2cf57aea27a 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/child-workflows.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/child-workflows.md @@ -78,6 +78,17 @@ Essa forma contendo apenas filhos continua útil quando cada membro paralelo é Se precisar combinar workflows filhos e atividades na mesma etapa de convergência, use uma barreira mista `all([...])`. As esperas por filhos e por atividades compartilham o mesmo `parallel_group_id`, e o Waterline identifica essa barreira compartilhada como `parallel_group_kind = mixed`. Se um subgrupo misto ou apenas de filhos estiver dentro de um `all([...])` maior, o grupo mais interno ainda determina `parallel_group_id`, enquanto `parallel_group_path` preserva o caminho completo do grupo externo ao interno. +### Custo de uma ramificação ampla {#fan-out-cost} + +Cada encerramento de um filho bloqueia a execução pai enquanto registra o resultado do filho, verifica a barreira do grupo e atualiza as projeções do pai. A partir do Workflow 2.27, esse trabalho não cresce mais com o número de irmãos: um encerramento não lê o histórico de nenhum outro filho e executa um número fixo de consultas. Os encerramentos dos filhos de um mesmo pai continuam se revezando no bloqueio do pai, e o pai não pode executar sua própria tarefa de workflow enquanto um encerramento o mantém. + +Antes da 2.27, cada encerramento também relia o histórico e a execução de cada irmão, então encerrar todos os filhos de uma ramificação ampla custava um trabalho que crescia com o quadrado do número de filhos. + +Para ramificações com centenas de filhos, ou próximas do limite padrão de 1.000 filhos pendentes (`pending_child_count`, veja [Limites estruturais](../constraints/structural-limits.md)), divida o trabalho: + +- **Lotes:** inicie um grupo de filhos, aguarde-o com `all([...])` e então inicie o próximo grupo. +- **Uma árvore:** deixe cada filho iniciar seus próprios filhos, para que nenhum pai supervisione mais do que algumas centenas ao mesmo tempo. + ## Contrato de identidade {#identity-contract} - `child()->id()` e o `target_name` do Waterline referem-se ao ID da instância do workflow filho, estável ao longo da cadeia de execuções dessa instância. diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/monitoring.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/monitoring.md index 283e3843f39..191ca1dcc0f 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/monitoring.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/monitoring.md @@ -176,6 +176,8 @@ A verificação de saúde consultiva `replay_blocked_runs` (categoria `correctne O Server nativo informa `replay_blocked` e a verificação `replay_blocked_runs` a partir da 3.6.0. +A partir do Workflow 2.27, `operator_metrics.namespace_scope_refusals` conta o trabalho que a [lista de namespaces permitidos](./configuration/options.md#namespace-allowlist) do app recusou nos últimos 15 minutos, por namespace e caminho. `job` conta jobs enfileirados ignorados. `repair`, `timeout` e `schedule_tick` contam candidatos a reparo, prazos vencidos e agendamentos devidos que ficaram mais de dois minutos em um namespace fora da lista. A verificação de saúde consultiva `namespace_scope_refusals` avisa enquanto as recusas continuam chegando e é limpa 15 minutos após a última. As contagens ficam no cache padrão, então use um armazenamento compartilhado (Redis, banco de dados ou Memcached) para que o processo web que serve a saúde veja as contagens dos workers. + ### Falhas de tarefas de workflow no Server {#workflow-task-failure-metric} O Server informa tarefas de workflow com falha em `GET /api/system/metrics`, em `metrics.dw_workflow_task_consecutive_failures`: diff --git a/i18n/pt-BR/source-hashes.json b/i18n/pt-BR/source-hashes.json index 0cbd7a72844..3f24f58ae53 100644 --- a/i18n/pt-BR/source-hashes.json +++ b/i18n/pt-BR/source-hashes.json @@ -4,12 +4,12 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "ad5c8519be03ae1e7b6e5e03b05a886862fd67c603b241ecb5baf2be5cd59610", + "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", "configuration/microservices.md": "46dc4afa07588b78829a7e3d259177ce0cf40861f0e31b88dbb6de3a83aa5488", - "configuration/options.md": "6a55ce6dd9828ad20a024d8d495b254bf1e1eea51dda3abd51ef4008e1dc9e9d", + "configuration/options.md": "42c40c50ecdf9fc6eace79d212229dfe0dac119c23137225f0ce353952fbd549", "configuration/pruning-workflows.md": "6f6ee2be3bd185ffec764e86c3ed3cbd40c45f75d28671b4cd11226493e11afb", "configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6", "constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05", @@ -32,7 +32,7 @@ "failures-and-recovery.md": "a240727af9539cca9cceb6ab3ddea545c95f21402813365442929ea05c09e70c", "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", - "features/child-workflows.md": "278b634b8b48b94203309cdba27d6116897a2919cab19628add8cd85dadb08d3", + "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", @@ -63,7 +63,7 @@ "laravel-adoption.md": "be0890619736ee2362ee96b6b1f5f397f10fb58cb845448ac15b437ac3062b36", "mcp-workflows.md": "1c0b5bb7f2e5c7ca835dfdfa57bbe8f6624172c855f4e225057ac2377abf360e", "migration.md": "7304a53786d5e45d3a639c33386e6558e855ee77982883a5e051ef5084b8453b", - "monitoring.md": "afbf43eacdd7ab017c75478a5ee4cb08745f7e4513799f949e57fc7f4d0fec2a", + "monitoring.md": "346b8a5207b7d69cea63dc9bfec95bf1911d3038a9d30ad06939b13130079279", "operator-operating-envelope.md": "dc0cf13d8593e4ce2d8ec1912e45e61c9bf13f06abf7cc8c422379db5e3fa0ad", "platform-conformance.md": "2eec7eba9a65c010e03c4b2eb78afe4dddd6fd8170218b3194c49e3777124c91", "platform-protocol-specs.md": "ba9c69adfca7fb4a0dd982464b0ca69dd5a21de1e340edbe23b075ec0fb0c35c", diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/compatibility.md b/i18n/uk/docusaurus-plugin-content-docs/current/compatibility.md index 2d5b885817a..bb1551d5a03 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.26 | PHP 8.2+ у 8.x; PHP 8.3+ для Laravel 13 | `^12.69.0` або `^13.30.0` | +| Поточний вбудований Workflow 2.27 | 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.26.0/resources/laravel-embedded-upgrade-contract.json) +Першоджерела пакета — [опублікований контракт вбудованого оновлення](https://github.com/durable-workflow/workflow/blob/2.27.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/) та @@ -152,6 +152,13 @@ Workflow 2.25 і 2.26 зберігають мінімальні вимоги 2.2 Див. примітки до випусків [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0) та [2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0). +Workflow 2.27 зберігає мінімальні вимоги підтримки з 2.21 і протокол вбудованого worker `1.22` та не додає міграцій бази даних. Зміни, які варто перевірити перед оновленням: + +- Починаючи з 2.27, вбудований застосунок відновлює й виконує роботу лише у власних просторах імен. Якщо застосунок запускає, планує workflow або надсилає їм сигнали в просторах імен, відмінних від `DW_V2_NAMESPACE`, перелічіть їх усі в `DW_V2_NAMESPACES`. Процес, що обслуговує всі простори імен, задає `DW_V2_ALL_NAMESPACES=true`. Див. [Які простори імен обслуговує застосунок](./configuration/options.md#namespace-allowlist). +- Починаючи з 2.27, закриття дочірнього workflow коштує батьківському однаково, скільки б сусідніх дочірніх workflow він не мав. Див. [Вартість широкого розгалуження](./features/child-workflows.md#fan-out-cost). + +Див. [примітки до випуску 2.27.0](https://github.com/durable-workflow/workflow/releases/tag/2.27.0). + ## Рівні стабільності {#stability-levels} Кожна публічна поверхня Durable Workflow має рівно один із цих рівнів diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/configuration/options.md b/i18n/uk/docusaurus-plugin-content-docs/current/configuration/options.md index 3de7a82d12f..defd0a1dc13 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/configuration/options.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/configuration/options.md @@ -167,6 +167,21 @@ $controlPlane->start('order-processing', 'order-12345', [ Коли простір імен не налаштований і не переданий явно, нові екземпляри зберігають простір імен `null`. Спостерігач, обмежений простором імен, не включає такі запуски. Зміна налаштувань не перепризначає наявні екземпляри. Запуск наявного екземпляра через інший простір імен відхиляється. +### Які простори імен обслуговує застосунок {#namespace-allowlist} + +Починаючи з Workflow 2.27, вбудований застосунок відновлює й виконує роботу лише в тих просторах імен, які він обслуговує. Це стосується watchdog, відновлення завдань, дедлайнів запусків і активностей, `workflow:v2:schedule-tick`, а також завдань у черзі для workflow, активностей, таймерів і викликів сервісів. Завдання в черзі для іншого простору імен пропускається ще до того, як матиме будь-який ефект, і в журнал записується попередження. + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- Якщо `DW_V2_NAMESPACES` не задано, застосунок обслуговує рівно `DW_V2_NAMESPACE`, тож застосунку з одним простором імен нічого змінювати не потрібно. +- Якщо задано, застосунок обслуговує рівно перелічені простори імен, тому додайте до списку й сам `DW_V2_NAMESPACE`. `default` позначає простір імен без явного значення. Порожнє значення не обслуговує жодного, а `*` відхиляється. +- Процес, який відновлює або виконує tick для всіх просторів імен у базі даних, наприклад окремий сервер, натомість задає `DW_V2_ALL_NAMESPACES=true`. + +Перелічіть кожен простір імен, у якому застосунок запускає, планує workflow або надсилає їм сигнали. Інакше їхні завдання й розклади чекатимуть на застосунок, що їх обслуговує. Цей список дозволених не дає одному застосунку виконувати роботу іншого з неправильним кодом чи обліковими даними. Це не ізоляція орендарів: застосунки зі спільною базою даних і далі можуть читати рядки одне одного. Відхилену роботу враховує `namespace_scope_refusals`; див. [Моніторинг](../monitoring.md#stuck-run-metrics). + ### Обмеження Waterline простором імен {#waterline-namespace-scoping} Коли Waterline розгорнуто зі спільною базою даних для кількох просторів імен, задайте `WATERLINE_NAMESPACE`, щоб обмежити всі списки одним простором: diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/features/child-workflows.md b/i18n/uk/docusaurus-plugin-content-docs/current/features/child-workflows.md index e38555ee207..674d61e0234 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/features/child-workflows.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/features/child-workflows.md @@ -78,6 +78,17 @@ final class ParentWorkflow extends Workflow Щоб поєднати дочірні workflow й activity в одному кроці збирання результатів, використовуйте змішаний бар’єр `all([...])`. Очікування дочірніх workflow та activity мають спільний `parallel_group_id`, а Waterline позначає цей бар’єр як `parallel_group_kind = mixed`. Якщо змішана або суто дочірня підгрупа вкладена в більшу `all([...])`, `parallel_group_id` визначає найвнутрішнішу групу, а `parallel_group_path` зберігає повний шлях від зовнішньої до внутрішньої. +### Вартість широкого розгалуження {#fan-out-cost} + +Кожне закриття дочірнього workflow блокує батьківський запуск, поки записує результат дочірнього workflow, перевіряє бар’єр групи й оновлює проєкції батьківського workflow. Починаючи з Workflow 2.27, ця робота більше не зростає з кількістю сусідніх дочірніх workflow: закриття не читає історію жодного іншого дочірнього workflow і виконує фіксовану кількість запитів. Закриття дочірніх workflow одного батька й далі по черзі отримують блокування батька, і батьківський workflow не може виконати власне завдання workflow, поки закриття утримує це блокування. + +До 2.27 кожне закриття також повторно читало історію та запуск кожного сусіднього дочірнього workflow, тож закриття всіх дочірніх workflow широкого розгалуження коштувало роботи, що зростала пропорційно квадрату їхньої кількості. + +Для розгалужень на сотні дочірніх workflow або близьких до типового ліміту в 1000 очікуваних дочірніх workflow (`pending_child_count`, див. [Структурні обмеження](../constraints/structural-limits.md)) розділіть роботу: + +- **Пакети:** запустіть групу дочірніх workflow, дочекайтеся її через `all([...])`, а потім запустіть наступну групу. +- **Дерево:** нехай кожен дочірній workflow запускає власні дочірні workflow, щоб жоден батько не наглядав одночасно більше ніж за кількома сотнями. + ## Контракт ідентичності {#identity-contract} - `child()->id()` та `target_name` у Waterline позначають ID екземпляра дочірнього workflow, який залишається сталим у всьому ланцюжку його запусків. diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/monitoring.md b/i18n/uk/docusaurus-plugin-content-docs/current/monitoring.md index 5b214c7c289..9027e73eb64 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/monitoring.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/monitoring.md @@ -173,6 +173,8 @@ signal, timer і дочірні workflow в порядку подій, коже Нативний Server повідомляє `replay_blocked` і перевірку `replay_blocked_runs` починаючи з 3.6.0. +Починаючи з Workflow 2.27, `operator_metrics.namespace_scope_refusals` рахує роботу, яку [список дозволених просторів імен](./configuration/options.md#namespace-allowlist) застосунку відхилив за останні 15 хвилин, за простором імен і шляхом. `job` рахує пропущені завдання в черзі. `repair`, `timeout` і `schedule_tick` рахують кандидатів на відновлення, прострочені дедлайни й розклади до виконання, що понад дві хвилини лишалися в просторі імен поза списком. Рекомендаційна перевірка стану `namespace_scope_refusals` попереджає, поки відмови надходять, і скидається через 15 хвилин після останньої. Лічильники зберігаються в типовому сховищі кешу, тож використовуйте спільне сховище (Redis, базу даних або Memcached), щоб вебпроцес, який віддає стан, бачив лічильники worker-процесів. + ### Збої завдань workflow у Server {#workflow-task-failure-metric} Server повідомляє про невдалі завдання workflow у `GET /api/system/metrics`, у полі `metrics.dw_workflow_task_consecutive_failures`: diff --git a/i18n/uk/source-hashes.json b/i18n/uk/source-hashes.json index 0cbd7a72844..3f24f58ae53 100644 --- a/i18n/uk/source-hashes.json +++ b/i18n/uk/source-hashes.json @@ -4,12 +4,12 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "ad5c8519be03ae1e7b6e5e03b05a886862fd67c603b241ecb5baf2be5cd59610", + "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", "configuration/microservices.md": "46dc4afa07588b78829a7e3d259177ce0cf40861f0e31b88dbb6de3a83aa5488", - "configuration/options.md": "6a55ce6dd9828ad20a024d8d495b254bf1e1eea51dda3abd51ef4008e1dc9e9d", + "configuration/options.md": "42c40c50ecdf9fc6eace79d212229dfe0dac119c23137225f0ce353952fbd549", "configuration/pruning-workflows.md": "6f6ee2be3bd185ffec764e86c3ed3cbd40c45f75d28671b4cd11226493e11afb", "configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6", "constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05", @@ -32,7 +32,7 @@ "failures-and-recovery.md": "a240727af9539cca9cceb6ab3ddea545c95f21402813365442929ea05c09e70c", "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", - "features/child-workflows.md": "278b634b8b48b94203309cdba27d6116897a2919cab19628add8cd85dadb08d3", + "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", @@ -63,7 +63,7 @@ "laravel-adoption.md": "be0890619736ee2362ee96b6b1f5f397f10fb58cb845448ac15b437ac3062b36", "mcp-workflows.md": "1c0b5bb7f2e5c7ca835dfdfa57bbe8f6624172c855f4e225057ac2377abf360e", "migration.md": "7304a53786d5e45d3a639c33386e6558e855ee77982883a5e051ef5084b8453b", - "monitoring.md": "afbf43eacdd7ab017c75478a5ee4cb08745f7e4513799f949e57fc7f4d0fec2a", + "monitoring.md": "346b8a5207b7d69cea63dc9bfec95bf1911d3038a9d30ad06939b13130079279", "operator-operating-envelope.md": "dc0cf13d8593e4ce2d8ec1912e45e61c9bf13f06abf7cc8c422379db5e3fa0ad", "platform-conformance.md": "2eec7eba9a65c010e03c4b2eb78afe4dddd6fd8170218b3194c49e3777124c91", "platform-protocol-specs.md": "ba9c69adfca7fb4a0dd982464b0ca69dd5a21de1e340edbe23b075ec0fb0c35c", 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 f0d571f8317..539d91bde8a 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.26 | PHP 8.x 中的 8.2+;Laravel 13 需要 PHP 8.3+ | `^12.69.0` 或 `^13.30.0` | +| 当前嵌入式 Workflow 2.27 | 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.26.0/resources/laravel-embedded-upgrade-contract.json) +包的依据是[已发布的嵌入式升级契约](https://github.com/durable-workflow/workflow/blob/2.27.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/)保持独立。 @@ -111,6 +111,13 @@ Workflow 2.25 和 2.26 保留 2.21 的支持下限和嵌入式 worker 协议 `1. 参见 [2.25.0](https://github.com/durable-workflow/workflow/releases/tag/2.25.0) 和 [2.26.0](https://github.com/durable-workflow/workflow/releases/tag/2.26.0) 的发布说明。 +Workflow 2.27 保持 2.21 的支持下限和嵌入式 worker 协议 `1.22`,不新增数据库迁移。升级前需要检查的变更: + +- 从 2.27 起,嵌入式应用只修复和运行自己命名空间中的工作。如果应用在 `DW_V2_NAMESPACE` 以外的命名空间中启动、调度工作流或向其发送信号,请把它们全部列入 `DW_V2_NAMESPACES`。服务所有命名空间的进程应设置 `DW_V2_ALL_NAMESPACES=true`。参见[应用运行哪些命名空间](./configuration/options.md#namespace-allowlist)。 +- 从 2.27 起,无论有多少兄弟子工作流,关闭一个子工作流给父工作流带来的工作量都相同。参见[大规模扇出的开销](./features/child-workflows.md#fan-out-cost)。 + +参见 [2.27.0 发布说明](https://github.com/durable-workflow/workflow/releases/tag/2.27.0)。 + ## 稳定性级别 {#stability-levels} Durable Workflow 中每个公开接口恰好具有以下一个稳定性级别。级别必须明确;未分类的接口不是公开接口。 diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/configuration/options.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/configuration/options.md index dd8ab5c48cb..a727225097a 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/configuration/options.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/configuration/options.md @@ -167,6 +167,21 @@ $controlPlane->start('order-processing', 'order-12345', [ 未配置命名空间且未显式传入时,新实例的命名空间保留为 `null`。限定命名空间的观察者不会包含这些运行。更改配置不会重新分配已有实例。通过不同命名空间启动已有实例会被拒绝。 +### 应用运行哪些命名空间 {#namespace-allowlist} + +从 Workflow 2.27 起,嵌入式应用只修复和运行它所服务的命名空间中的工作。范围包括 watchdog、任务修复、运行和活动的截止时间、`workflow:v2:schedule-tick`,以及排队的工作流、活动、计时器和服务调用作业。属于其他命名空间的排队作业会在产生任何效果之前被跳过,并记录一条警告。 + +```env +DW_V2_NAMESPACE=production +DW_V2_NAMESPACES=production,billing +``` + +- 未设置 `DW_V2_NAMESPACES` 时,应用只服务 `DW_V2_NAMESPACE`,因此只有一个命名空间的应用无需更改。 +- 设置后,应用只服务列出的命名空间,所以请把 `DW_V2_NAMESPACE` 本身也列进去。`default` 表示未指定的命名空间。空值不服务任何命名空间,`*` 会被拒绝。 +- 修复或 tick 数据库中所有命名空间的进程(例如独立服务器)应改为设置 `DW_V2_ALL_NAMESPACES=true`。 + +请列出应用启动、调度工作流或向其发送信号的每个命名空间。否则这些命名空间的任务和调度会一直等待某个服务它们的应用。这个允许列表可以防止一个应用用错误的代码或凭据运行另一个应用的工作。它不是租户隔离:共享同一数据库的应用仍然可以读取彼此的行。被拒绝的工作会计入 `namespace_scope_refusals`;参见[监控](../monitoring.md#stuck-run-metrics)。 + ### Waterline 命名空间范围 {#waterline-namespace-scoping} Waterline 部署在包含多个命名空间的共享数据库上时,设置 `WATERLINE_NAMESPACE` 可将所有列表视图限制在一个命名空间: diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/child-workflows.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/child-workflows.md index fa45af3b59a..ff340904677 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/child-workflows.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/child-workflows.md @@ -78,6 +78,17 @@ final class ParentWorkflow extends Workflow 需要在同一扇入步骤中组合子工作流和活动时,使用一个混合 `all([...])` 屏障。子工作流等待和活动等待共享 `parallel_group_id`,Waterline 将共享屏障标记为 `parallel_group_kind = mixed`。混合或纯子工作流子组嵌套在更大的 `all([...])` 内时,最内层组仍决定 `parallel_group_id`,而 `parallel_group_path` 保留完整的从外到内路径。 +### 大规模扇出的开销 {#fan-out-cost} + +每次子工作流关闭时,都会锁定父运行,同时记录子工作流的结果、检查组屏障并更新父工作流的投影。从 Workflow 2.27 起,这部分工作不再随兄弟子工作流的数量增长:一次关闭不会读取其他任何子工作流的历史,只执行固定数量的查询。同一父工作流的子工作流关闭仍会轮流获取父工作流的锁,并且在某次关闭持有该锁期间,父工作流无法执行自己的工作流任务。 + +在 2.27 之前,每次关闭还会重新读取每个兄弟子工作流的历史和运行,因此关闭大规模扇出的全部子工作流所需的工作量随子工作流数量的平方增长。 + +当扇出达到数百个子工作流,或接近默认的 1,000 个待处理子工作流上限(`pending_child_count`,参见[结构限制](../constraints/structural-limits.md))时,请拆分工作: + +- **分批:** 启动一组子工作流,用 `all([...])` 等待它完成,然后再启动下一组。 +- **树形:** 让每个子工作流启动自己的子工作流,使任何一个父工作流同时监管的子工作流不超过几百个。 + ## 标识契约 {#identity-contract} - `child()->id()` 和 Waterline `target_name` 指向子工作流实例 ID,在该实例的整个运行链中保持稳定。 diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/monitoring.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/monitoring.md index bfeba6a6409..0a13d0ebeaf 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/monitoring.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/monitoring.md @@ -132,6 +132,8 @@ trace、run、activity、attempt 和 request ID 保持独立。baggage 使用默 原生 Server 从 3.6.0 起会报告 `replay_blocked` 和 `replay_blocked_runs` 检查。 +从 Workflow 2.27 起,`operator_metrics.namespace_scope_refusals` 按命名空间和路径统计应用的[命名空间允许列表](./configuration/options.md#namespace-allowlist)在过去 15 分钟内拒绝的工作。`job` 统计被跳过的排队作业。`repair`、`timeout` 和 `schedule_tick` 统计在允许列表之外的命名空间中滞留超过两分钟的修复候选、已过期的截止时间和到期的调度。建议性健康检查 `namespace_scope_refusals` 在拒绝持续出现时发出警告,并在最后一次拒绝 15 分钟后清除。计数保存在默认缓存存储中,因此请使用共享存储(Redis、数据库或 Memcached),让提供健康检查的 Web 进程能看到 worker 的计数。 + ### Server 工作流任务失败 {#workflow-task-failure-metric} Server 在 `GET /api/system/metrics` 的 `metrics.dw_workflow_task_consecutive_failures` 下报告失败的工作流任务: diff --git a/i18n/zh-Hans/source-hashes.json b/i18n/zh-Hans/source-hashes.json index 0cbd7a72844..3f24f58ae53 100644 --- a/i18n/zh-Hans/source-hashes.json +++ b/i18n/zh-Hans/source-hashes.json @@ -4,12 +4,12 @@ "ai-agent-workflow-engine.md": "28016466b179adbabdff6467ce351100c9bee48529a8bec9df7ec22c8d786d4d", "ai-assisted-development.md": "b246bb60585fb7a69bc534978f470f3f16e899e1f8f203ba0847d2d11b8a1ec3", "capabilities.md": "d9a2bbc0d04adf8cb3f4c7f42d779a43aafab60791210305e7e476c0499528fc", - "compatibility.md": "ad5c8519be03ae1e7b6e5e03b05a886862fd67c603b241ecb5baf2be5cd59610", + "compatibility.md": "a1b478309cdb159ee2c15b3e1ced7aba7f8c5172ad7431b2e3db907b0c868147", "configuration/customization-matrix.md": "3d115863eaee7852b541bcd01615f424cc19c5847c7cd7d75e5ae63bc3f5cc78", "configuration/database-connection.md": "cc83ae77133236309506fa44d39bfd0c939c32a6154c0bd6099bc64c83bdaec9", "configuration/ensuring-same-server.md": "6c665f37cc198c7b1a775a60a94aab5ff4e55383385e76f1834c7840559b512a", "configuration/microservices.md": "46dc4afa07588b78829a7e3d259177ce0cf40861f0e31b88dbb6de3a83aa5488", - "configuration/options.md": "6a55ce6dd9828ad20a024d8d495b254bf1e1eea51dda3abd51ef4008e1dc9e9d", + "configuration/options.md": "42c40c50ecdf9fc6eace79d212229dfe0dac119c23137225f0ce353952fbd549", "configuration/pruning-workflows.md": "6f6ee2be3bd185ffec764e86c3ed3cbd40c45f75d28671b4cd11226493e11afb", "configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6", "constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05", @@ -32,7 +32,7 @@ "failures-and-recovery.md": "a240727af9539cca9cceb6ab3ddea545c95f21402813365442929ea05c09e70c", "features/activity-execution-model.md": "e8c37520ae46a7efb30438f4fc06bf893c1df430cb1f92c48963697adaf09082", "features/cancel-and-terminate.md": "cedd1e6c51dfa551e00edc1d39739ff1f67d558d2a0be92143f478cb6111536b", - "features/child-workflows.md": "278b634b8b48b94203309cdba27d6116897a2919cab19628add8cd85dadb08d3", + "features/child-workflows.md": "30dd8e1a131654d6320641446b6bd661f27cd591353a60d007574955749cf8fb", "features/concurrency.md": "a7a3eb2274f7b14faf722494569b7663c07ab48afdf2e9225e58914b84cacbb4", "features/condition-waits.md": "451261eda990c9591a0db69839d872184b5c64da6b537a582133095b8d4b599e", "features/continue-as-new.md": "a5309192c685abeb5295071d423824ae2287e68d247a6661f18d3ab21f9bdc9c", @@ -63,7 +63,7 @@ "laravel-adoption.md": "be0890619736ee2362ee96b6b1f5f397f10fb58cb845448ac15b437ac3062b36", "mcp-workflows.md": "1c0b5bb7f2e5c7ca835dfdfa57bbe8f6624172c855f4e225057ac2377abf360e", "migration.md": "7304a53786d5e45d3a639c33386e6558e855ee77982883a5e051ef5084b8453b", - "monitoring.md": "afbf43eacdd7ab017c75478a5ee4cb08745f7e4513799f949e57fc7f4d0fec2a", + "monitoring.md": "346b8a5207b7d69cea63dc9bfec95bf1911d3038a9d30ad06939b13130079279", "operator-operating-envelope.md": "dc0cf13d8593e4ce2d8ec1912e45e61c9bf13f06abf7cc8c422379db5e3fa0ad", "platform-conformance.md": "2eec7eba9a65c010e03c4b2eb78afe4dddd6fd8170218b3194c49e3777124c91", "platform-protocol-specs.md": "ba9c69adfca7fb4a0dd982464b0ca69dd5a21de1e340edbe23b075ec0fb0c35c", diff --git a/static/stable-releases.json b/static/stable-releases.json index c616fadbf6e..f63cdaef293 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.26.0" + "workflow": "2.27.0" }, "helm_chart": { "app_version": "3.8.0",