Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/features/timeouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ $result = activity(
);
```

In service mode, closing an activity attempt does not forcibly stop SDK application code. Python SDK 2.9.0 reports a refusal at the next heartbeat; code that never heartbeats can run until it returns, and a physical thread slot remains occupied until exit. See [Python heartbeat refusals and callback exit](../polyglot/python.md#heartbeat-refusals-and-callback-exit).

### Schedule-to-start timeout

The deadline is computed when the activity is scheduled. If no worker claims the activity before the deadline, the `TaskWatchdog` enforces the timeout. If retry attempts remain, a new activity task is scheduled with the snapped backoff and the schedule-to-start deadline is recomputed relative to the retry's available-at time — each retry gets a fresh window. If no `scheduleToStartTimeout` was configured, the deadline is cleared on retry. If all attempts are exhausted, a terminal `ActivityTimedOut` history event is recorded and the workflow is woken.
Expand Down
8 changes: 8 additions & 0 deletions docs/polyglot/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,14 @@ The direct `Client.heartbeat_activity_task()` call uses the configured `Transpor

Do not suppress heartbeat/ownership failures and continue external work or report success. Progress is not an external commit or a resumable-checkpoint receipt. Keep external effects idempotent.

### Heartbeat refusals and callback exit {#heartbeat-refusals-and-callback-exit}

In **Python SDK 2.9.0**, `ctx.heartbeat()` and `ctx.heartbeat_sync()` raise `ActivityLeaseAuthorityLost` when a heartbeat response says `can_continue=false`. The exception retains the original Server reason, such as `activity_deadline_elapsed`, `attempt_closed` or `run_closed`. A cancellation request instead raises `ActivityCancelled`. See the [published SDK qualification](https://github.com/durable-workflow/sdk-python/issues/186#issuecomment-6361330674).

The heartbeat that observes the refusal is a cooperative exit point. Stop external work and propagate the exception; do not catch it and return success. Code that never heartbeats can keep running until it returns. A helper heartbeat cannot forcibly interrupt a blocked library call: use finite I/O deadlines and the call's own cancellation mechanism.

The physical activity slot stays occupied until the callback/thread exits. Losing attempt authority does not make that thread available for replacement work, and the worker does not publish a late result for the closed attempt. Runtime timeout enforcement and stopping application code are separate boundaries. See [activity timeouts](../features/timeouts.md#activity-timeouts) and the [helper-thread guidance](#heartbeat-helper-thread).

### Non-Retryable Errors

Raise `NonRetryableError` to fail the activity without retries:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ $result = activity(
);
```

Im Service-Modus hält das Schließen eines Activity-Versuchs den SDK-Anwendungscode nicht zwangsweise an. Python SDK 2.9.0 meldet die Ablehnung beim nächsten Heartbeat; Code ohne Heartbeats kann bis zur Rückkehr weiterlaufen, und der physische Thread-Slot bleibt bis zum Ende belegt. Siehe [Heartbeat-Ablehnungen und Callback-Ende in Python](../polyglot/python.md#heartbeat-refusals-and-callback-exit).

### Zeitlimit von Planung bis Start {#schedule-to-start-timeout}

Die Frist wird bei der Planung der Aktivität berechnet. Beansprucht kein Worker sie rechtzeitig, setzt `TaskWatchdog` das Zeitlimit durch. Sind weitere Versuche möglich, wird eine neue Aufgabe mit der gespeicherten Wartezeit geplant und die Schedule-to-start-Frist relativ zur Verfügbarkeit dieses Versuchs neu berechnet. Jeder Versuch erhält ein neues Fenster. Ohne konfiguriertes `scheduleToStartTimeout` wird die Frist beim Wiederholungsversuch gelöscht. Nach Ausschöpfen aller Versuche wird ein terminales `ActivityTimedOut`-Ereignis gespeichert und der Workflow geweckt.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,14 @@ Der direkte Aufruf von `Client.heartbeat_activity_task()` verwendet die konfigur

Unterdrücken Sie Heartbeat- oder Besitzfehler nicht, um externe Arbeit fortzusetzen oder Erfolg zu melden. Fortschritt ist weder ein externer Commit noch eine Bestätigung eines fortsetzbaren Prüfpunkts. Halten Sie externe Effekte idempotent.

### Heartbeat-Ablehnung und Ende des Callbacks {#heartbeat-refusals-and-callback-exit}

Im **Python SDK 2.9.0** lösen `ctx.heartbeat()` und `ctx.heartbeat_sync()` einen `ActivityLeaseAuthorityLost` aus, wenn eine Heartbeat-Antwort `can_continue=false` enthält. Die Ausnahme bewahrt den ursprünglichen Server-Grund, etwa `activity_deadline_elapsed`, `attempt_closed` oder `run_closed`. Eine Abbruchanforderung löst dagegen `ActivityCancelled` aus. Siehe die [Qualifikation des veröffentlichten SDK](https://github.com/durable-workflow/sdk-python/issues/186#issuecomment-6361330674).

Der Heartbeat, der die Ablehnung empfängt, ist ein kooperativer Ausstiegspunkt. Beenden Sie externe Arbeit und reichen Sie die Ausnahme weiter; fangen Sie sie nicht ab, um Erfolg zurückzugeben. Code ohne Heartbeats kann bis zur Rückkehr weiterlaufen. Ein Hilfs-Heartbeat kann einen blockierten Bibliotheksaufruf nicht zwangsweise unterbrechen: Verwenden Sie endliche E/A-Fristen und den eigenen Abbruchmechanismus des Aufrufs.

Der physische Activity-Slot bleibt bis zum Ende des Callbacks/Threads belegt. Der Verlust der Ausführungsberechtigung gibt diesen Thread nicht für andere Arbeit frei, und der Worker veröffentlicht kein verspätetes Ergebnis für den geschlossenen Versuch. Die Durchsetzung eines Runtime-Timeouts und das Anhalten von Anwendungscode sind getrennte Grenzen. Siehe [Activity-Timeouts](../features/timeouts.md#activity-timeouts) und die [Hinweise zum Hilfsthread](#heartbeat-helper-thread).

### Nicht wiederholbare Fehler {#non-retryable-errors}

Lösen Sie `NonRetryableError` aus, um eine Aktivität ohne Wiederholungen scheitern zu lassen:
Expand Down
4 changes: 2 additions & 2 deletions i18n/de/source-hashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822",
"features/signals.md": "2816f53ec12f5ae88906a399a9681e8a517677d64ce6c063dd4eb205c46f370b",
"features/sticky-execution.md": "d54fe85283d633d5cba10a03c716a707bf3b6a4e6d47ec9859e17f5f676a89b8",
"features/timeouts.md": "785dea4e9b8f8fa9c0c9e880b8c20f1847745c244391800e289fa9ccd9438699",
"features/timeouts.md": "e9c1b46c679dae3acfcdc199b8f3e07defd7b114dfd2d8fe6c9ac20285b776aa",
"features/timers.md": "94a017d85c9dc7e8e598ce895bb722523422e3729b1935ede777ed7dd2734db7",
"features/updates.md": "ecc24a4ae764edf0281430583216d47d4b75fd9f58d183f7dd5bc9794cbd1c06",
"features/versioning.md": "3686d25c27aa8a4f576b1fb01c554c6d58f8fa91363d64314830a325872a1ed3",
Expand Down Expand Up @@ -82,7 +82,7 @@
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
"polyglot/python.md": "174acc170fc749284b5115f995996885c04056340d44bd334c6cee33e288abd1",
"polyglot/python.md": "8776584d0bb4b5667f719e698cea654f53f16cf927265fae27c2930779188648",
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "0bb9929cafe2751e1fde615ee033e127c5f6c6eaa8d4bbae941b4e1e86b06d58",
"polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ $result = activity(
);
```

En modo servicio, cerrar un intento de actividad no detiene por la fuerza el código de la aplicación del SDK. Python SDK 2.9.0 comunica el rechazo en el siguiente heartbeat; el código sin heartbeats puede ejecutarse hasta retornar y la plaza física del hilo permanece ocupada hasta su salida. Consulte [rechazos de heartbeat y salida del callback en Python](../polyglot/python.md#heartbeat-refusals-and-callback-exit).

### Tiempo de espera de programación a inicio {#schedule-to-start-timeout}

El plazo se calcula al programar la actividad. Si ningún worker la reclama antes, `TaskWatchdog` aplica el tiempo de espera. Si quedan intentos, se programa una nueva tarea de actividad con la espera registrada y el plazo schedule-to-start se recalcula desde el momento en que el nuevo intento esté disponible. Cada intento recibe una ventana nueva. Si no se configuró `scheduleToStartTimeout`, el plazo se borra al reintentar. Si se agotan los intentos, se registra el evento terminal `ActivityTimedOut` y se despierta el workflow.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,14 @@ La llamada directa a `Client.heartbeat_activity_task()` usa la `TransportRetryPo

No suprima fallos de heartbeat o de titularidad para seguir haciendo trabajo externo o informar de éxito. El progreso no es una confirmación externa ni un recibo de punto de control reanudable. Mantenga idempotentes los efectos externos.

### Rechazo de heartbeats y salida del callback {#heartbeat-refusals-and-callback-exit}

En **Python SDK 2.9.0**, `ctx.heartbeat()` y `ctx.heartbeat_sync()` lanzan `ActivityLeaseAuthorityLost` cuando una respuesta de heartbeat indica `can_continue=false`. La excepción conserva el motivo original del Server, como `activity_deadline_elapsed`, `attempt_closed` o `run_closed`. Una solicitud de cancelación lanza `ActivityCancelled`. Consulte la [validación del SDK publicado](https://github.com/durable-workflow/sdk-python/issues/186#issuecomment-6361330674).

El heartbeat que observa el rechazo es un punto de salida cooperativa. Detenga el trabajo externo y propague la excepción; no la capture para devolver un resultado correcto. El código que nunca envía heartbeats puede seguir ejecutándose hasta retornar. Un heartbeat auxiliar no puede interrumpir por la fuerza una llamada bloqueada de una biblioteca: use plazos finitos de E/S y el mecanismo de cancelación de la propia llamada.

La plaza física de actividad permanece ocupada hasta que sale el callback/hilo. Perder la autoridad del intento no libera ese hilo para otro trabajo, y el worker no publica un resultado tardío del intento cerrado. Aplicar el timeout del runtime y detener el código de la aplicación son límites distintos. Consulte los [timeouts de actividad](../features/timeouts.md#activity-timeouts) y la [guía del hilo auxiliar](#heartbeat-helper-thread).

### Errores no reintentables {#non-retryable-errors}

Lanza `NonRetryableError` para fallar sin reintentos:
Expand Down
4 changes: 2 additions & 2 deletions i18n/es/source-hashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822",
"features/signals.md": "2816f53ec12f5ae88906a399a9681e8a517677d64ce6c063dd4eb205c46f370b",
"features/sticky-execution.md": "d54fe85283d633d5cba10a03c716a707bf3b6a4e6d47ec9859e17f5f676a89b8",
"features/timeouts.md": "785dea4e9b8f8fa9c0c9e880b8c20f1847745c244391800e289fa9ccd9438699",
"features/timeouts.md": "e9c1b46c679dae3acfcdc199b8f3e07defd7b114dfd2d8fe6c9ac20285b776aa",
"features/timers.md": "94a017d85c9dc7e8e598ce895bb722523422e3729b1935ede777ed7dd2734db7",
"features/updates.md": "ecc24a4ae764edf0281430583216d47d4b75fd9f58d183f7dd5bc9794cbd1c06",
"features/versioning.md": "3686d25c27aa8a4f576b1fb01c554c6d58f8fa91363d64314830a325872a1ed3",
Expand Down Expand Up @@ -82,7 +82,7 @@
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
"polyglot/python.md": "174acc170fc749284b5115f995996885c04056340d44bd334c6cee33e288abd1",
"polyglot/python.md": "8776584d0bb4b5667f719e698cea654f53f16cf927265fae27c2930779188648",
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "0bb9929cafe2751e1fde615ee033e127c5f6c6eaa8d4bbae941b4e1e86b06d58",
"polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ $result = activity(
);
```

En mode service, fermer une tentative d’activité n’arrête pas de force le code applicatif du SDK. Le SDK Python 2.9.0 signale le refus au prochain heartbeat ; le code sans heartbeat peut s’exécuter jusqu’à son retour et le créneau physique du thread reste occupé jusqu’à sa sortie. Consultez les [refus de heartbeat et la sortie du callback en Python](../polyglot/python.md#heartbeat-refusals-and-callback-exit).

### Délai entre planification et démarrage {#schedule-to-start-timeout}

L’échéance est calculée à la planification de l’activité. Si aucun worker ne l’a réclamée à temps, `TaskWatchdog` applique le délai. S’il reste des tentatives, une nouvelle tâche est planifiée avec le recul enregistré et l’échéance schedule-to-start est recalculée depuis la disponibilité du nouvel essai. Chaque tentative reçoit une nouvelle fenêtre. Sans `scheduleToStartTimeout` configuré, l’échéance est effacée lors du nouvel essai. Une fois toutes les tentatives épuisées, un événement terminal `ActivityTimedOut` est enregistré et le workflow est réveillé.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,14 @@ L’appel direct à `Client.heartbeat_activity_task()` utilise la `TransportRetr

Ne masquez pas les échecs de heartbeat ou de possession pour poursuivre le travail externe ou annoncer une réussite. La progression n’est ni une validation externe ni une confirmation de point de reprise. Gardez les effets externes idempotents.

### Refus du heartbeat et sortie du callback {#heartbeat-refusals-and-callback-exit}

Avec le **SDK Python 2.9.0**, `ctx.heartbeat()` et `ctx.heartbeat_sync()` lèvent `ActivityLeaseAuthorityLost` lorsqu’une réponse de heartbeat indique `can_continue=false`. L’exception conserve le motif initial du Server, par exemple `activity_deadline_elapsed`, `attempt_closed` ou `run_closed`. Une demande d’annulation lève plutôt `ActivityCancelled`. Consultez la [qualification du SDK publié](https://github.com/durable-workflow/sdk-python/issues/186#issuecomment-6361330674).

Le heartbeat qui constate le refus constitue un point de sortie coopérative. Arrêtez le travail externe et propagez l’exception ; ne l’interceptez pas pour renvoyer un succès. Le code qui n’envoie jamais de heartbeat peut continuer jusqu’à son retour. Un heartbeat auxiliaire ne peut pas interrompre de force un appel de bibliothèque bloqué : utilisez des échéances d’E/S finies et le mécanisme d’annulation propre à l’appel.

Le créneau physique de l’activité reste occupé jusqu’à la sortie du callback/thread. La perte d’autorité de la tentative ne libère pas ce thread pour un autre travail, et le worker ne publie pas de résultat tardif pour la tentative fermée. L’application du timeout par le runtime et l’arrêt du code applicatif sont des limites distinctes. Consultez les [timeouts d’activité](../features/timeouts.md#activity-timeouts) et les [conseils pour le thread auxiliaire](#heartbeat-helper-thread).

### Erreurs non réessayables {#non-retryable-errors}

Levez `NonRetryableError` pour faire échouer l'activité sans nouvelle tentative :
Expand Down
4 changes: 2 additions & 2 deletions i18n/fr/source-hashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822",
"features/signals.md": "2816f53ec12f5ae88906a399a9681e8a517677d64ce6c063dd4eb205c46f370b",
"features/sticky-execution.md": "d54fe85283d633d5cba10a03c716a707bf3b6a4e6d47ec9859e17f5f676a89b8",
"features/timeouts.md": "785dea4e9b8f8fa9c0c9e880b8c20f1847745c244391800e289fa9ccd9438699",
"features/timeouts.md": "e9c1b46c679dae3acfcdc199b8f3e07defd7b114dfd2d8fe6c9ac20285b776aa",
"features/timers.md": "94a017d85c9dc7e8e598ce895bb722523422e3729b1935ede777ed7dd2734db7",
"features/updates.md": "ecc24a4ae764edf0281430583216d47d4b75fd9f58d183f7dd5bc9794cbd1c06",
"features/versioning.md": "3686d25c27aa8a4f576b1fb01c554c6d58f8fa91363d64314830a325872a1ed3",
Expand Down Expand Up @@ -82,7 +82,7 @@
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
"polyglot/python.md": "174acc170fc749284b5115f995996885c04056340d44bd334c6cee33e288abd1",
"polyglot/python.md": "8776584d0bb4b5667f719e698cea654f53f16cf927265fae27c2930779188648",
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "0bb9929cafe2751e1fde615ee033e127c5f6c6eaa8d4bbae941b4e1e86b06d58",
"polyglot/server-api-reference.md": "e94af77a13b341d6fdc9941d4ee94e5053ab932d2e77069b238eb33351414e83",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ $result = activity(
);
```

サービスモードでは、アクティビティの試行を閉じても SDK のアプリケーションコードは強制停止されません。Python SDK 2.9.0 は次のハートビートで拒否を通知します。ハートビートを送らないコードは戻るまで実行を続ける可能性があり、物理スレッドのスロットは終了まで占有されます。[Python のハートビート拒否とコールバック終了](../polyglot/python.md#heartbeat-refusals-and-callback-exit)を参照してください。

### スケジュールから開始までのタイムアウト {#schedule-to-start-timeout}

期限はアクティビティをスケジュールした時点で計算します。期限までに Worker が取得しなければ、`TaskWatchdog` がタイムアウトを適用します。試行回数が残っていれば、固定済みのバックオフで新しいタスクをスケジュールし、その実行可能時刻から開始待ち期限を再計算します。各再試行には新しい時間枠が与えられます。`scheduleToStartTimeout` が未設定なら、再試行時にこの期限を消去します。すべての試行が尽きると、終端の `ActivityTimedOut` 履歴を記録してワークフローを起こします。
Expand Down
Loading
Loading