diff --git a/docs/polyglot/rust.md b/docs/polyglot/rust.md index 3fbc805dcb4..629c7495a48 100644 --- a/docs/polyglot/rust.md +++ b/docs/polyglot/rust.md @@ -248,6 +248,40 @@ Heartbeat availability follows actual claimed tasks, including input/history loa Handlers are async futures on Tokio and must yield for other work to progress. Use `tokio::task::spawn_blocking` or a separate process for blocking work, with an explicit cancellation and shutdown boundary. Raising concurrency does not provide CPU isolation or make a detached thread cancellable. See the [Worker API](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html) for the installed SDK's controls. +## Received activity retry budgets {#activity-retry-info} + +Rust SDK **4.8.0 or newer** exposes `ActivityContext::retry_info()` in service activity handlers. Check the installed crate in `Cargo.lock`: the separately selected installation pin above can be older. The returned `ActivityRetryInfo` preserves the original `attempt_number()` and received `policy()` JSON, including unknown fields. It is an immutable snapshot of this invocation, independent of mutable compatibility fields on the context. + +Use `attempt_limit()` and `is_last_configured_attempt()` to interpret the received budget: + +| Received retry policy | `ActivityAttemptLimit` | Final configured attempt | +| --- | --- | --- | +| Object with positive integer `max_attempts: n` | `Bounded(n)`, including the first attempt | `Some(true)` once the original attempt reaches or exceeds `n`, otherwise `Some(false)` | +| Object with `max_attempts: null` | `Unlimited` | `Some(false)` | +| Omitted policy, root null, missing field or invalid limit | `Unknown` | `None` | + +The helper also returns `None` for an invalid zero attempt number. A runtime's scheduling default does not establish received metadata: the published Server 2.11.0 no-authored-policy control omits the snapshot and therefore reports `Unknown`, not an inferred `Bounded(1)`. `policy()` distinguishes an omitted policy from a received JSON null without treating either as unlimited. The [normal installed acceptance](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791) includes this control and the recipe below. + +For a final-configured-attempt fallback or application alert, register a handler on your existing Worker: + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` is not a promise of another execution. Non-retryable failure, cancellation, workflow closure and elapsed deadlines can end work before its configured budget is used. The helper does not change retry admission or grant extra time. + +Local activities and direct `testing::WorkflowEnvironment::run_activity` calls have no received Server snapshot and report unknown policy. Fresh `run_workflow` tests expose the modeled snapshot recorded in their generated history. These test semantics do not prove a deployed Server sends a policy. See [ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) and [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html). + ## Local activities Rust SDK 3.1.0 adds inline local execution on workers configured with diff --git a/i18n/de/docusaurus-plugin-content-docs/current/polyglot/rust.md b/i18n/de/docusaurus-plugin-content-docs/current/polyglot/rust.md index 7f896fae80c..20f2f65261c 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/polyglot/rust.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/polyglot/rust.md @@ -248,6 +248,40 @@ Die Heartbeat-Verfügbarkeit folgt tatsächlich beanspruchten Tasks einschließl Handler sind async Futures auf Tokio und müssen Ausführungszeit abgeben. Verwenden Sie für blockierende Arbeit `tokio::task::spawn_blocking` oder einen separaten Prozess mit ausdrücklicher Abbruch- und Shutdown-Grenze. Mehr Parallelität isoliert keine CPU und macht einen abgetrennten Thread nicht abbrechbar. Siehe die [Worker-API](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html) des installierten SDKs. +## Empfangene Wiederholungsbudgets für Aktivitäten {#activity-retry-info} + +Rust SDK **4.8.0 oder neuer** stellt `ActivityContext::retry_info()` in Aktivitätshandlern im Service-Modus bereit. Prüfen Sie das installierte Crate in `Cargo.lock`: Die oben separat gewählte Installationsversion kann älter sein. Der zurückgegebene `ActivityRetryInfo` bewahrt die ursprüngliche `attempt_number()` und das empfangene `policy()`-JSON einschließlich unbekannter Felder. Dieser unveränderliche Snapshot des Aufrufs ist von veränderbaren Kompatibilitätsfeldern des Kontexts unabhängig. + +Verwenden Sie `attempt_limit()` und `is_last_configured_attempt()`, um das empfangene Budget auszuwerten: + +| Empfangene Wiederholungsrichtlinie | `ActivityAttemptLimit` | Letzter konfigurierter Versuch | +| --- | --- | --- | +| Objekt mit positiver Ganzzahl `max_attempts: n` | `Bounded(n)` einschließlich des ersten Versuchs | `Some(true)`, sobald der ursprüngliche Versuch `n` erreicht oder überschreitet, andernfalls `Some(false)` | +| Objekt mit `max_attempts: null` | `Unlimited` | `Some(false)` | +| Fehlende Richtlinie, null auf oberster Ebene, fehlendes Feld oder ungültige Grenze | `Unknown` | `None` | + +Der Helper gibt auch bei einer ungültigen Versuchsnummer null `None` zurück. Ein Planungsstandard des Runtimes belegt keine empfangenen Metadaten: Der veröffentlichte Server-2.11.0-Kontrollfall ohne ausdrücklich verfasste Richtlinie lässt den Snapshot aus und meldet daher `Unknown` statt eines abgeleiteten `Bounded(1)`. `policy()` unterscheidet eine fehlende Richtlinie von empfangenem JSON null, ohne eines davon als unbegrenzt zu behandeln. Die [Abnahme mit normal installiertem Paket](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791) umfasst diesen Kontrollfall und das folgende Beispiel. + +Registrieren Sie für einen Fallback oder Anwendungsalarm beim letzten konfigurierten Versuch einen Handler an Ihrem vorhandenen Worker: + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` verspricht keine weitere Ausführung. Ein nicht wiederholbarer Fehler, Abbruch, Workflow-Abschluss oder abgelaufene Fristen können die Arbeit beenden, bevor das konfigurierte Budget ausgeschöpft ist. Der Helper ändert weder die Zulassung von Wiederholungen noch gewährt er zusätzliche Zeit. + +Lokale Aktivitäten und direkte Aufrufe von `testing::WorkflowEnvironment::run_activity` haben keinen empfangenen Server-Snapshot und melden eine unbekannte Richtlinie. Neue `run_workflow`-Tests zeigen den modellierten Snapshot aus ihrer erzeugten Historie. Diese Testsemantik belegt nicht, dass ein bereitgestellter Server eine Richtlinie sendet. Siehe [ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) und [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html). + ## Lokale Aktivitäten {#local-activities} Rust SDK 3.1.0 ergänzt lokale Inline-Ausführung auf Workern mit diff --git a/i18n/de/source-hashes.json b/i18n/de/source-hashes.json index 19f0a3f0330..70c088a7f6c 100644 --- a/i18n/de/source-hashes.json +++ b/i18n/de/source-hashes.json @@ -84,7 +84,7 @@ "polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c", "polyglot/python.md": "d55056ca7638df07b7267bc6d62e635b954957b99620478e861df90558860df3", "polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3", - "polyglot/rust.md": "1466f1f9b417708d88f6d89efa055c2d92e2ee93e9508cf82eb05fa1dc801a88", + "polyglot/rust.md": "f6ac50f08ee1a7e94686403df5880e771cd306aa07aed69c73261e5a25f6d78f", "polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83", "polyglot/server-config-reference.md": "edb4cf00b9df2c9946b32a81c6bb2c4db6eaee89794b85286c61c235a4846414", "polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2", diff --git a/i18n/es/docusaurus-plugin-content-docs/current/polyglot/rust.md b/i18n/es/docusaurus-plugin-content-docs/current/polyglot/rust.md index cf9117d2665..5639cbab330 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/polyglot/rust.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/polyglot/rust.md @@ -195,6 +195,40 @@ La disponibilidad anunciada en heartbeats sigue las tareas realmente reclamadas, Los handlers son futures async de Tokio y deben ceder el control. Use `tokio::task::spawn_blocking` o un proceso separado para trabajo bloqueante, con límites explícitos de cancelación y apagado. Aumentar concurrencia no aísla CPU ni hace cancelable un thread desacoplado. Consulte la [API de Worker](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html) del SDK instalado. +## Presupuestos de reintento recibidos por la actividad {#activity-retry-info} + +Rust SDK **4.8.0 o posterior** ofrece `ActivityContext::retry_info()` en los manejadores de actividades del servicio. Comprueba el crate instalado en `Cargo.lock`: la versión de instalación seleccionada por separado arriba puede ser anterior. El `ActivityRetryInfo` devuelto conserva el `attempt_number()` original y el JSON de `policy()` recibido, incluidos los campos desconocidos. Es una instantánea inmutable de esta invocación, independiente de los campos de compatibilidad mutables del contexto. + +Usa `attempt_limit()` e `is_last_configured_attempt()` para interpretar el presupuesto recibido: + +| Política de reintento recibida | `ActivityAttemptLimit` | Último intento configurado | +| --- | --- | --- | +| Objeto con entero positivo `max_attempts: n` | `Bounded(n)`, incluido el primer intento | `Some(true)` cuando el intento original alcanza o supera `n`; en otro caso, `Some(false)` | +| Objeto con `max_attempts: null` | `Unlimited` | `Some(false)` | +| Política omitida, null raíz, campo ausente o límite inválido | `Unknown` | `None` | + +El helper también devuelve `None` ante un número de intento cero inválido. El valor predeterminado de planificación del runtime no demuestra los metadatos recibidos: el control publicado de Server 2.11.0 sin política escrita omite la instantánea y devuelve `Unknown`, sin inferir `Bounded(1)`. `policy()` distingue una política omitida de un JSON null recibido sin interpretar ninguno como ilimitado. La [aceptación con instalación normal](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791) incluye este control y la receta siguiente. + +Para elegir una alternativa o registrar una alerta de aplicación en el último intento configurado, registra un manejador en tu Worker existente: + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` no promete otra ejecución. Un fallo no reintentable, la cancelación, el cierre del workflow y los plazos agotados pueden terminar el trabajo antes de consumir el presupuesto configurado. El helper no cambia la admisión de reintentos ni concede tiempo adicional. + +Las actividades locales y las llamadas directas a `testing::WorkflowEnvironment::run_activity` no tienen una instantánea recibida del Server y devuelven política desconocida. Las pruebas nuevas con `run_workflow` exponen la instantánea modelada que registran en su historial generado. Esta semántica de pruebas no demuestra que un Server desplegado envíe una política. Consulta [ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) y [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html). + ## Actividades locales {#local-activities} El SDK de Rust 3.1.0 añade ejecución local en el propio worker con `Worker::local_activities(true)`. Registra callbacks con los métodos ordinarios de registro de actividades y utiliza los métodos de actividad local del contexto de workflow. Consulta el [ejemplo ejecutable](https://github.com/durable-workflow/sdk-rust/blob/3.1.0/examples/local_activities.rs) y la [referencia de LocalActivityOptions](https://rust.durable-workflow.com/durable_workflow/struct.LocalActivityOptions.html) para configurar reintentos y tiempos de espera. diff --git a/i18n/es/source-hashes.json b/i18n/es/source-hashes.json index 19f0a3f0330..70c088a7f6c 100644 --- a/i18n/es/source-hashes.json +++ b/i18n/es/source-hashes.json @@ -84,7 +84,7 @@ "polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c", "polyglot/python.md": "d55056ca7638df07b7267bc6d62e635b954957b99620478e861df90558860df3", "polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3", - "polyglot/rust.md": "1466f1f9b417708d88f6d89efa055c2d92e2ee93e9508cf82eb05fa1dc801a88", + "polyglot/rust.md": "f6ac50f08ee1a7e94686403df5880e771cd306aa07aed69c73261e5a25f6d78f", "polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83", "polyglot/server-config-reference.md": "edb4cf00b9df2c9946b32a81c6bb2c4db6eaee89794b85286c61c235a4846414", "polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2", diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/rust.md b/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/rust.md index 172a986ddc3..1eb2fa09c8d 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/rust.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/rust.md @@ -252,6 +252,40 @@ La disponibilité des heartbeats suit les tâches réellement réclamées : char Les handlers sont des futures async Tokio et doivent céder la main. Utilisez `tokio::task::spawn_blocking` ou un processus séparé pour le travail bloquant, avec une limite explicite d’annulation et d’arrêt. Augmenter la concurrence n’isole pas le CPU et ne rend pas un thread détaché annulable. Voir l’[API Worker](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html) du SDK installé. +## Budgets de tentatives reçus par une activité {#activity-retry-info} + +Rust SDK **4.8.0 ou ultérieur** expose `ActivityContext::retry_info()` dans les gestionnaires d’activités en mode service. Vérifiez le crate installé dans `Cargo.lock` : la version d’installation sélectionnée séparément ci-dessus peut être plus ancienne. Le `ActivityRetryInfo` renvoyé conserve le `attempt_number()` original et le JSON `policy()` reçu, y compris les champs inconnus. Cet instantané immuable de l’invocation est indépendant des champs de compatibilité modifiables du contexte. + +Utilisez `attempt_limit()` et `is_last_configured_attempt()` pour interpréter le budget reçu : + +| Politique de tentatives reçue | `ActivityAttemptLimit` | Dernière tentative configurée | +| --- | --- | --- | +| Objet avec un entier positif `max_attempts: n` | `Bounded(n)`, première tentative comprise | `Some(true)` lorsque la tentative originale atteint ou dépasse `n`, sinon `Some(false)` | +| Objet avec `max_attempts: null` | `Unlimited` | `Some(false)` | +| Politique omise, null à la racine, champ absent ou limite invalide | `Unknown` | `None` | + +Le helper renvoie aussi `None` pour un numéro de tentative nul invalide. Le comportement de planification par défaut du runtime ne prouve pas les métadonnées reçues : le contrôle publié sur Server 2.11.0 sans politique définie par l’auteur omet l’instantané et indique donc `Unknown`, sans déduire `Bounded(1)`. `policy()` distingue une politique omise d’un JSON null reçu sans considérer l’un ou l’autre comme illimité. L’[acceptation avec installation normale](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791) comprend ce contrôle et l’exemple ci-dessous. + +Pour choisir une solution de repli ou enregistrer une alerte applicative lors de la dernière tentative configurée, enregistrez un gestionnaire sur votre Worker existant : + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` ne promet pas une nouvelle exécution. Un échec non réessayable, l’annulation, la fermeture du workflow ou des échéances dépassées peuvent terminer le travail avant épuisement du budget configuré. Le helper ne change pas l’admission des tentatives et n’accorde pas de temps supplémentaire. + +Les activités locales et les appels directs à `testing::WorkflowEnvironment::run_activity` n’ont pas d’instantané reçu du Server et indiquent une politique inconnue. Les nouveaux tests `run_workflow` exposent l’instantané modélisé enregistré dans leur historique généré. Cette sémantique de test ne prouve pas qu’un Server déployé transmet une politique. Voir [ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) et [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html). + ## Activités locales {#local-activities} Le SDK Rust 3.1.0 ajoute l’exécution locale en ligne sur les workers configurés diff --git a/i18n/fr/source-hashes.json b/i18n/fr/source-hashes.json index 19f0a3f0330..70c088a7f6c 100644 --- a/i18n/fr/source-hashes.json +++ b/i18n/fr/source-hashes.json @@ -84,7 +84,7 @@ "polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c", "polyglot/python.md": "d55056ca7638df07b7267bc6d62e635b954957b99620478e861df90558860df3", "polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3", - "polyglot/rust.md": "1466f1f9b417708d88f6d89efa055c2d92e2ee93e9508cf82eb05fa1dc801a88", + "polyglot/rust.md": "f6ac50f08ee1a7e94686403df5880e771cd306aa07aed69c73261e5a25f6d78f", "polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83", "polyglot/server-config-reference.md": "edb4cf00b9df2c9946b32a81c6bb2c4db6eaee89794b85286c61c235a4846414", "polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2", diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/rust.md b/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/rust.md index a579dad55ca..3be2b0e8a28 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/rust.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/rust.md @@ -195,6 +195,40 @@ let mut worker = Worker::new(client.clone(), "payments") ハンドラーは Tokio の async future であり、他の処理が進むよう実行権を譲る必要があります。ブロックする処理には `tokio::task::spawn_blocking` または別プロセスを使い、キャンセルと終了の境界を明示してください。並行数を増やしても CPU は分離されず、切り離されたスレッドがキャンセル可能になるわけでもありません。インストールした SDK の [Worker API](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html) を参照してください。 +## 受信したアクティビティのリトライ予算 {#activity-retry-info} + +Rust SDK **4.8.0 以降**では、サービスモードのアクティビティハンドラーで `ActivityContext::retry_info()` を使えます。`Cargo.lock` でインストール済み crate を確認してください。上の独立したインストール指定は旧版の場合があります。返される `ActivityRetryInfo` は、元の `attempt_number()` と受信した `policy()` JSON を未知のフィールドも含めて保持します。この呼び出しの変更不能なスナップショットであり、コンテキストの変更可能な互換性フィールドには依存しません。 + +受信した予算は `attempt_limit()` と `is_last_configured_attempt()` で解釈します。 + +| 受信したリトライポリシー | `ActivityAttemptLimit` | 設定上の最終試行 | +| --- | --- | --- | +| 正の整数 `max_attempts: n` を持つオブジェクト | 初回を含む `Bounded(n)` | 元の試行番号が `n` 以上なら `Some(true)`、それ以外は `Some(false)` | +| `max_attempts: null` を持つオブジェクト | `Unlimited` | `Some(false)` | +| ポリシー省略、ルートの null、フィールド欠落、不正な上限 | `Unknown` | `None` | + +試行番号が不正なゼロの場合も、ヘルパーは `None` を返します。ランタイムのスケジュール既定値は受信メタデータの証明にはなりません。公開済み Server 2.11.0 の明示的なポリシーなしの対照実行では、スナップショットが省略されるため、`Bounded(1)` を推定せず `Unknown` を返します。`policy()` はポリシー省略と受信した JSON null を区別しますが、どちらも無制限とは扱いません。 [通常インストールでの受け入れ検証](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791)には、この対照実行と以下の例が含まれます。 + +設定上の最終試行でフォールバックを選ぶ、またはアプリケーションのアラートを記録するには、既存の Worker にハンドラーを登録します。 + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` は次の実行を保証しません。再試行不可の失敗、キャンセル、ワークフローの終了、期限切れにより、設定した予算を使い切る前に処理が終わることがあります。このヘルパーはリトライの受け入れを変更せず、追加時間も与えません。 + +ローカルアクティビティと `testing::WorkflowEnvironment::run_activity` の直接呼び出しには、受信した Server スナップショットがなく、ポリシーは不明になります。新規の `run_workflow` テストでは、生成した履歴に記録するモデル上のスナップショットを公開します。このテスト仕様は、デプロイ済み Server がポリシーを送信する証明にはなりません。[ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) と [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html) を参照してください。 + ## ローカルアクティビティ {#local-activities} Rust SDK 3.1.0 は `Worker::local_activities(true)` で設定した Worker にインラインのローカル実行を追加します。通常のアクティビティ登録メソッドでコールバックを登録し、ワークフローコンテキストのローカルアクティビティメソッドを使います。再試行とタイムアウトの設定は[実行可能な例](https://github.com/durable-workflow/sdk-rust/blob/3.1.0/examples/local_activities.rs)と [LocalActivityOptions リファレンス](https://rust.durable-workflow.com/durable_workflow/struct.LocalActivityOptions.html)を参照してください。 diff --git a/i18n/ja/source-hashes.json b/i18n/ja/source-hashes.json index 19f0a3f0330..70c088a7f6c 100644 --- a/i18n/ja/source-hashes.json +++ b/i18n/ja/source-hashes.json @@ -84,7 +84,7 @@ "polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c", "polyglot/python.md": "d55056ca7638df07b7267bc6d62e635b954957b99620478e861df90558860df3", "polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3", - "polyglot/rust.md": "1466f1f9b417708d88f6d89efa055c2d92e2ee93e9508cf82eb05fa1dc801a88", + "polyglot/rust.md": "f6ac50f08ee1a7e94686403df5880e771cd306aa07aed69c73261e5a25f6d78f", "polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83", "polyglot/server-config-reference.md": "edb4cf00b9df2c9946b32a81c6bb2c4db6eaee89794b85286c61c235a4846414", "polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2", diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/rust.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/rust.md index 22279456c21..aebb702e548 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/rust.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/rust.md @@ -247,6 +247,40 @@ A disponibilidade dos heartbeats acompanha as tarefas realmente adquiridas, incl Handlers são futures async do Tokio e precisam ceder o controle. Use `tokio::task::spawn_blocking` ou outro processo para trabalho bloqueante, com limites explícitos de cancelamento e encerramento. Aumentar concorrência não fornece isolamento de CPU nem torna cancelável uma thread desacoplada. Veja a [API de Worker](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html) do SDK instalado. +## Orçamentos de tentativas recebidos pela atividade {#activity-retry-info} + +Rust SDK **4.8.0 ou posterior** oferece `ActivityContext::retry_info()` nos handlers de atividades em modo de serviço. Confira o crate instalado em `Cargo.lock`: a versão de instalação selecionada separadamente acima pode ser anterior. O `ActivityRetryInfo` retornado preserva o `attempt_number()` original e o JSON de `policy()` recebido, inclusive campos desconhecidos. É um snapshot imutável dessa invocação, independente dos campos de compatibilidade mutáveis do contexto. + +Use `attempt_limit()` e `is_last_configured_attempt()` para interpretar o orçamento recebido: + +| Política de tentativas recebida | `ActivityAttemptLimit` | Última tentativa configurada | +| --- | --- | --- | +| Objeto com inteiro positivo `max_attempts: n` | `Bounded(n)`, incluindo a primeira tentativa | `Some(true)` quando a tentativa original alcança ou ultrapassa `n`; caso contrário, `Some(false)` | +| Objeto com `max_attempts: null` | `Unlimited` | `Some(false)` | +| Política omitida, null na raiz, campo ausente ou limite inválido | `Unknown` | `None` | + +O helper também retorna `None` para um número de tentativa zero inválido. O padrão de agendamento do runtime não comprova os metadados recebidos: o controle publicado do Server 2.11.0 sem política definida pelo autor omite o snapshot e informa `Unknown`, sem inferir `Bounded(1)`. `policy()` distingue uma política omitida de um JSON null recebido sem tratar nenhum deles como ilimitado. A [aceitação com instalação normal](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791) inclui esse controle e a receita abaixo. + +Para escolher um fallback ou registrar um alerta da aplicação na última tentativa configurada, registre um handler no Worker existente: + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` não promete outra execução. Falha não repetível, cancelamento, fechamento do workflow e prazos esgotados podem encerrar o trabalho antes de consumir o orçamento configurado. O helper não altera a admissão de tentativas nem concede tempo extra. + +Atividades locais e chamadas diretas a `testing::WorkflowEnvironment::run_activity` não têm snapshot recebido do Server e informam política desconhecida. Testes novos de `run_workflow` expõem o snapshot modelado registrado no histórico gerado. Essa semântica de testes não comprova que um Server implantado envie uma política. Veja [ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) e [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html). + ## Atividades locais {#local-activities} O SDK Rust 3.1.0 adiciona execução local inline em workers configurados com diff --git a/i18n/pt-BR/source-hashes.json b/i18n/pt-BR/source-hashes.json index 19f0a3f0330..70c088a7f6c 100644 --- a/i18n/pt-BR/source-hashes.json +++ b/i18n/pt-BR/source-hashes.json @@ -84,7 +84,7 @@ "polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c", "polyglot/python.md": "d55056ca7638df07b7267bc6d62e635b954957b99620478e861df90558860df3", "polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3", - "polyglot/rust.md": "1466f1f9b417708d88f6d89efa055c2d92e2ee93e9508cf82eb05fa1dc801a88", + "polyglot/rust.md": "f6ac50f08ee1a7e94686403df5880e771cd306aa07aed69c73261e5a25f6d78f", "polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83", "polyglot/server-config-reference.md": "edb4cf00b9df2c9946b32a81c6bb2c4db6eaee89794b85286c61c235a4846414", "polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2", diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/rust.md b/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/rust.md index 8eb69b10903..f4d462e0972 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/rust.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/rust.md @@ -248,6 +248,40 @@ let mut worker = Worker::new(client.clone(), "payments") Обробники є async future у Tokio і повинні віддавати керування. Для блокувальної роботи використовуйте `tokio::task::spawn_blocking` або окремий процес із явними межами скасування та завершення. Більша паралельність не ізолює CPU і не робить від’єднаний потік скасовуваним. Перегляньте [Worker API](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html) для встановленої версії SDK. +## Отримані бюджети retries для activity {#activity-retry-info} + +Rust SDK **4.8.0 або новіший** надає `ActivityContext::retry_info()` в обробниках service activity. Перевірте встановлений crate у `Cargo.lock`: окремо вибрана версія встановлення вище може бути старішою. Повернений `ActivityRetryInfo` зберігає початковий `attempt_number()` та отриманий JSON `policy()`, включно з невідомими полями. Це незмінний snapshot цього виклику, незалежний від змінюваних полів сумісності контексту. + +Використовуйте `attempt_limit()` і `is_last_configured_attempt()` для тлумачення отриманого бюджету: + +| Отримана retry policy | `ActivityAttemptLimit` | Остання налаштована спроба | +| --- | --- | --- | +| Об’єкт із додатним цілим `max_attempts: n` | `Bounded(n)`, включно з першою спробою | `Some(true)`, коли початкова спроба досягає або перевищує `n`, інакше `Some(false)` | +| Об’єкт із `max_attempts: null` | `Unlimited` | `Some(false)` | +| Відсутня policy, кореневий null, відсутнє поле або невалідний ліміт | `Unknown` | `None` | + +Helper також повертає `None` для невалідного нульового номера спроби. Типове планування runtime не доводить наявності отриманих метаданих: опублікований контроль Server 2.11.0 без явно заданої policy не містить snapshot, тому повертає `Unknown`, а не виведений `Bounded(1)`. `policy()` відрізняє відсутню policy від отриманого JSON null, не вважаючи жодне з них unlimited. [Перевірка звичайно встановленого пакета](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791) охоплює цей контроль і наведений нижче приклад. + +Для fallback останньої налаштованої спроби або сповіщення застосунку зареєструйте обробник у наявному Worker: + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` не обіцяє нового виконання. Non-retryable failure, скасування, закриття workflow і сплив deadlines можуть завершити роботу до вичерпання налаштованого бюджету. Helper не змінює допуск retries і не надає додаткового часу. + +Local activities та прямі виклики `testing::WorkflowEnvironment::run_activity` не мають отриманого snapshot сервера й повертають невідому policy. Нові тести `run_workflow` надають змодельований snapshot, записаний у їхній згенерованій історії. Ця семантика тестів не доводить, що розгорнутий Server передає policy. Див. [ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) та [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html). + ## Локальні activity {#local-activities} Rust SDK 3.1.0 додає inline local execution на workers із налаштуванням diff --git a/i18n/uk/source-hashes.json b/i18n/uk/source-hashes.json index 19f0a3f0330..70c088a7f6c 100644 --- a/i18n/uk/source-hashes.json +++ b/i18n/uk/source-hashes.json @@ -84,7 +84,7 @@ "polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c", "polyglot/python.md": "d55056ca7638df07b7267bc6d62e635b954957b99620478e861df90558860df3", "polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3", - "polyglot/rust.md": "1466f1f9b417708d88f6d89efa055c2d92e2ee93e9508cf82eb05fa1dc801a88", + "polyglot/rust.md": "f6ac50f08ee1a7e94686403df5880e771cd306aa07aed69c73261e5a25f6d78f", "polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83", "polyglot/server-config-reference.md": "edb4cf00b9df2c9946b32a81c6bb2c4db6eaee89794b85286c61c235a4846414", "polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2", diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/rust.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/rust.md index 7aa3dfa5ca7..b659921f2f4 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/rust.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/rust.md @@ -195,6 +195,40 @@ let mut worker = Worker::new(client.clone(), "payments") 处理函数作为 Tokio async future 执行,必须让出执行权。阻塞工作应使用 `tokio::task::spawn_blocking` 或独立进程,并设置明确的取消和关闭边界。提高并发不会隔离 CPU,也不会使脱离管理的线程可取消。参见已安装 SDK 的 [Worker API](https://rust.durable-workflow.com/durable_workflow/struct.Worker.html)。 +## 活动收到的重试预算 {#activity-retry-info} + +Rust SDK **4.8.0 或更新版本**在服务模式活动处理函数中提供 `ActivityContext::retry_info()`。请检查 `Cargo.lock` 中实际安装的 crate:上方独立选择的安装版本可能更旧。返回的 `ActivityRetryInfo` 保留原始 `attempt_number()` 和收到的 `policy()` JSON,包括未知字段。这是本次调用的不可变快照,不受上下文中可变兼容字段影响。 + +使用 `attempt_limit()` 和 `is_last_configured_attempt()` 解释收到的预算: + +| 收到的重试策略 | `ActivityAttemptLimit` | 配置的最后一次尝试 | +| --- | --- | --- | +| 含正整数 `max_attempts: n` 的对象 | `Bounded(n)`,包括首次尝试 | 原始尝试编号达到或超过 `n` 时为 `Some(true)`,否则为 `Some(false)` | +| 含 `max_attempts: null` 的对象 | `Unlimited` | `Some(false)` | +| 策略省略、根 null、字段缺失或无效上限 | `Unknown` | `None` | + +对于无效的零尝试编号,辅助方法也返回 `None`。运行时的调度默认值不能证明收到的元数据:已发布 Server 2.11.0 的未编写策略对照会省略快照,因此报告 `Unknown`,而非推断为 `Bounded(1)`。`policy()` 区分策略省略与收到 JSON null,但不会将任一情况视为无限重试。 [正常安装验收](https://github.com/durable-workflow/sdk-rust/issues/135#issuecomment-6366200791)包含此对照和下方示例。 + +若要在配置的最后一次尝试中选择回退或记录应用告警,请在现有 Worker 上注册处理函数: + +```rust +use durable_workflow::{json, Worker}; + +pub fn register_charge(worker: &mut Worker) { + worker.register_activity("charge", |ctx, _| async move { + let retry = ctx.retry_info(); + if retry.is_last_configured_attempt() == Some(true) { + // Select a final-attempt fallback or record an application alert. + } + Ok(json!({"attempt": retry.attempt_number()})) + }); +} +``` + +`Some(false)` 不保证还有下一次执行。不可重试失败、取消、工作流关闭或期限耗尽都可能在用完配置预算前结束工作。该辅助方法不会改变重试准入,也不会额外延长期限。 + +本地活动和直接调用 `testing::WorkflowEnvironment::run_activity` 没有收到的 Server 快照,会报告未知策略。新的 `run_workflow` 测试公开其生成历史中记录的模型快照。这些测试语义不能证明已部署 Server 会发送策略。参见 [ActivityRetryInfo](https://rust.durable-workflow.com/durable_workflow/struct.ActivityRetryInfo.html) 和 [ActivityAttemptLimit](https://rust.durable-workflow.com/durable_workflow/enum.ActivityAttemptLimit.html)。 + ## 本地活动 {#local-activities} Rust SDK 3.1.0 在配置了 `Worker::local_activities(true)` 的 Worker 上增加内联本地执行。使用普通活动注册方法注册回调,然后使用工作流上下文的本地活动方法。重试和超时配置见[可运行示例](https://github.com/durable-workflow/sdk-rust/blob/3.1.0/examples/local_activities.rs)及 [LocalActivityOptions 参考](https://rust.durable-workflow.com/durable_workflow/struct.LocalActivityOptions.html)。 diff --git a/i18n/zh-Hans/source-hashes.json b/i18n/zh-Hans/source-hashes.json index 19f0a3f0330..70c088a7f6c 100644 --- a/i18n/zh-Hans/source-hashes.json +++ b/i18n/zh-Hans/source-hashes.json @@ -84,7 +84,7 @@ "polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c", "polyglot/python.md": "d55056ca7638df07b7267bc6d62e635b954957b99620478e861df90558860df3", "polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3", - "polyglot/rust.md": "1466f1f9b417708d88f6d89efa055c2d92e2ee93e9508cf82eb05fa1dc801a88", + "polyglot/rust.md": "f6ac50f08ee1a7e94686403df5880e771cd306aa07aed69c73261e5a25f6d78f", "polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83", "polyglot/server-config-reference.md": "edb4cf00b9df2c9946b32a81c6bb2c4db6eaee89794b85286c61c235a4846414", "polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",