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
12 changes: 12 additions & 0 deletions docs/constraints/execution-guarantees.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ final class ChargeCard extends Activity

For Rust service-mode activities, SDK **4.9.0 or newer** exposes the original optional `activity_execution_id()`, `workflow_id()` (instance) and `run_id()` through `ActivityContext`. Use the logical activity ID across retries; missing claim fields stay `None`, and a per-attempt task/attempt ID is not a replacement. The [Rust handler recipe](../polyglot/rust.md#activity-identity) derives a downstream key and explains older-Server, local-activity and Server-free-test limits. A key still needs an idempotent downstream API or durable effect ledger; these accessors do not provide resumable checkpoints.

Python service-mode activities expose the read-only optional
`activity.context().info.activity_execution_id`, with `workflow_id` and `run_id`
for the owning workflow instance and run. Use the logical execution ID across
retries. Missing identity stays `None`; never substitute a task, attempt or
session ID. The [Python identity guide](../polyglot/python.md#activity-identity)
links the SDK-owned service example and defines legacy, session, prepared-local,
inline-local and Server-free behavior. Its named published-package/native
Server receipt proves ordinary retry identity only. The ID is public metadata,
not claim authority, and does not make an external effect exactly once. Keep
downstream idempotency, distinct keys for different effects and outcome
reconciliation.

## What Developers Must Make Idempotent

You do **not** need to make workflow replay itself idempotent. The framework
Expand Down
30 changes: 30 additions & 0 deletions docs/polyglot/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,36 @@ async def long_running_task(items: list) -> dict:
return {"processed": len(items)}
```

#### Logical activity execution identity {#activity-identity}

Python SDK 2.15.0 and later expose the read-only optional
`activity.context().info.activity_execution_id`. It identifies one logical
activity execution across retries. `info.workflow_id` and `info.run_id`
identify its owning workflow instance and run. Use the logical execution ID
for an external service's idempotency key. Task IDs and attempt IDs change
on retry and must not replace it.

Missing, invalid or blank execution IDs remain `None`, including on older
claims. Nonblank received strings retain their exact spelling. If an operation
requires this key, refuse it before performing the external effect when the
ID is unavailable. Session-routed activities use their ordinary claim identity.
Prepared local activities use their validated admission receipt's execution
ID. Inline local activities have no admitted execution ID and expose `None`,
while retaining parent workflow/run IDs. Server-free mocks do not create
Server activity identity.

Use the SDK's [idempotency-key helper and activity identity guide](https://python.durable-workflow.com/sdk-reference/#activity-execution-identity)
for the service-mode example. Give different external operations stable
operation suffixes, and ensure the downstream service honors the key. An
execution ID is public metadata, not proof of a live claim or authorization
for an external effect. Keep credentials, current-attempt fencing and outcome
reconciliation. The [published-package ordinary retry receipt](https://github.com/durable-workflow/.github/issues/211#issuecomment-6869562527)
binds Python SDK 2.17.2 to native Server 3.9.2. It proves a stable logical
execution/workflow/run identity and distinct task/attempt IDs across attempts
1 and 2. Local and session behavior retain their separately defined scope.
See [execution guarantees](../constraints/execution-guarantees.md#service-activity-identity)
for the shared idempotency contract.

#### Received retry policy and original attempt {#activity-retry-metadata}

Requires Python SDK **2.12.0 or later**. `info = activity.context().info`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ final class ChargeCard extends Activity

Für Rust-Aktivitäten im Service-Modus liefert SDK **4.9.0 oder neuer** die ursprünglichen optionalen Werte `activity_execution_id()`, `workflow_id()` (Instanz) und `run_id()` über `ActivityContext`. Nutzen Sie die logische Aktivitäts-ID über Retries hinweg; fehlende Claim-Felder bleiben `None`, und eine Task- oder Versuch-ID ist kein Ersatz. Das [Rust-Handler-Beispiel](../polyglot/rust.md#activity-identity) leitet einen externen Schlüssel ab und erläutert Grenzen älterer Server, lokaler Aktivitäten und serverfreier Tests. Der Schlüssel benötigt weiterhin eine idempotente externe API oder ein dauerhaftes Effektregister; diese Methoden liefern keine fortsetzbaren Checkpoints.

Python-Aktivitäten im Dienstmodus stellen das schreibgeschützte optionale Feld
`activity.context().info.activity_execution_id` sowie `workflow_id` und `run_id`
für die zugehörige Workflow-Instanz und den Run bereit. Verwenden Sie die
logische Ausführungs-ID über Wiederholungen hinweg. Fehlende Identität bleibt
`None`. Ersetzen Sie sie niemals durch eine Task-, Versuchs- oder Sitzungs-ID.
Der [Python-Identitätsleitfaden](../polyglot/python.md#activity-identity) verlinkt
das Dienstmodus-Beispiel des SDKs und definiert das Verhalten älterer Claims,
von Sitzungen, vorbereiteten und inline ausgeführten lokalen Aktivitäten sowie
Tests ohne Server. Sein benannter Beleg mit veröffentlichtem Paket und nativem
Server belegt nur die Identität bei gewöhnlichen Wiederholungen. Die ID ist
öffentliche Metainformation, keine Claim-Autorität, und macht einen externen Effekt
nicht Exactly-once. Behalten Sie nachgelagerte Idempotenz, unterschiedliche
Schlüssel für verschiedene Effekte und Ergebnisabgleich bei.

## Was die Anwendung idempotent machen muss {#what-developers-must-make-idempotent}

Workflow-Replay selbst müssen Sie nicht idempotent machen. Das Framework rekonstruiert den Zustand aus der festgeschriebenen Historie.
Expand Down
35 changes: 35 additions & 0 deletions i18n/de/docusaurus-plugin-content-docs/current/polyglot/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,41 @@ async def long_running_task(items: list) -> dict:
return {"processed": len(items)}
```

#### Logische Aktivitätsausführung identifizieren {#activity-identity}

Python SDK 2.15.0 und neuer stellen das schreibgeschützte optionale Feld
`activity.context().info.activity_execution_id` bereit. Es identifiziert eine
logische Aktivitätsausführung über Wiederholungen hinweg. `info.workflow_id`
und `info.run_id` identifizieren die zugehörige Workflow-Instanz und den Run.
Verwenden Sie die logische Ausführungs-ID als Idempotenzschlüssel für einen
externen Dienst. Task-IDs und Versuchs-IDs ändern sich bei einer Wiederholung
und dürfen sie nicht ersetzen.

Fehlende, ungültige oder leere Ausführungs-IDs bleiben `None`, auch bei älteren
Claims. Empfangene Zeichenfolgen mit mindestens einem Nicht-Leerzeichen
behalten ihre exakte Schreibweise. Wenn eine Operation diesen Schlüssel
benötigt, lehnen Sie sie bei fehlender ID vor dem externen Effekt ab.
Sitzungsgebundene Aktivitäten verwenden die Identität ihres gewöhnlichen Claims.
Vorbereitete lokale Aktivitäten verwenden die Ausführungs-ID ihres validierten
Zulassungsbelegs. Inline ausgeführte lokale Aktivitäten besitzen keine
zugelassene Ausführungs-ID und liefern `None`, behalten aber die IDs ihres
übergeordneten Workflows und Runs. Mocks ohne Server erzeugen keine
Server-Aktivitätsidentität.

Das Dienstmodus-Beispiel finden Sie im [SDK-Leitfaden mit Idempotenzschlüssel-Helfer und Aktivitätsidentität](https://python.durable-workflow.com/sdk-reference/#activity-execution-identity).
Geben Sie verschiedenen externen Operationen stabile Operationssuffixe und
stellen Sie sicher, dass der nachgelagerte Dienst den Schlüssel berücksichtigt.
Eine Ausführungs-ID ist öffentliche Metainformation, kein Nachweis eines aktiven
Claims und keine Berechtigung für einen externen Effekt. Behalten Sie
Zugangsdaten, Fencing des aktuellen Versuchs und Ergebnisabgleich bei. Der
[Beleg für gewöhnliche Wiederholungen mit dem veröffentlichten Paket](https://github.com/durable-workflow/.github/issues/211#issuecomment-6869562527)
bindet Python SDK 2.17.2 an den nativen Server 3.9.2. Er belegt stabile
logische Ausführungs-, Workflow- und Run-Identität sowie unterschiedliche
Task- und Versuchs-IDs für die Versuche 1 und 2. Lokales und Sitzungsverhalten
behalten ihren gesondert definierten Geltungsbereich. Siehe
[Ausführungsgarantien](../constraints/execution-guarantees.md#service-activity-identity)
für den gemeinsamen Idempotenzvertrag.

#### Empfangene Wiederholungsrichtlinie und ursprünglicher Versuch {#activity-retry-metadata}

Erfordert Python SDK **2.12.0 oder neuer**. `info = activity.context().info`
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 @@ -14,7 +14,7 @@
"configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6",
"constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05",
"constraints/constraints-summary.md": "fb48d01502388fc3821eae3790f470ed29cec91545420450f96fc77b84e589f1",
"constraints/execution-guarantees.md": "c24aaff70bfcf50366459ec698ced67adff1e02c1b0ca23c8178a13873037f5a",
"constraints/execution-guarantees.md": "9e53840c400b14186587714b32dd54dd780aaa68f2a132fc1e4e4d1f3eeadd0b",
"constraints/idempotent-vs-deterministic.md": "f7396f01a4111ce187e751b009c1efb96f5538e8a602006eed24f7b1d8f44adf",
"constraints/overview.md": "fd6c842c6c22d6f0df37a52de15ca74b34664f5ecd78af0c08b1e0cdb9a2be1f",
"constraints/structural-limits.md": "5c7b7f6c86c5ca547eb3f200400ceab3b589f32d83866914f44e3a5a7d81e964",
Expand Down Expand Up @@ -84,7 +84,7 @@
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
"polyglot/python.md": "82da06617fe24e70c5c89197d192a81430a282b788ef93afd3b3bcb690ba2a9f",
"polyglot/python.md": "57734052d6ffae8d660083626bf47fb7c392c492ab0581a8942401046bb25d38",
"polyglot/runtime-migration.md": "5a78713bb8cb74aea58f6d5d826400d968a405f69c6ff17fdf2f7decb1d14b71",
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "31950634b8ccdb5c288ba871cc7f816de6683c52bf738bfdc13fa7aa825c6335",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ final class ChargeCard extends Activity

Para actividades Rust en modo servicio, SDK **4.9.0 o posterior** expone los valores originales opcionales `activity_execution_id()`, `workflow_id()` (instancia) y `run_id()` mediante `ActivityContext`. Usa el ID lógico de actividad entre reintentos; los campos ausentes del claim siguen en `None`, y un ID de tarea o intento no los sustituye. La [receta del handler Rust](../polyglot/rust.md#activity-identity) deriva una clave externa y explica los límites de Server anteriores, actividades locales y pruebas sin Server. La clave sigue necesitando una API externa idempotente o un registro duradero de efectos; estos métodos no proporcionan checkpoints reanudables.

Las actividades Python en modo servicio exponen el campo opcional de solo
lectura `activity.context().info.activity_execution_id`, con `workflow_id` y
`run_id` para la instancia de workflow y la ejecución a las que pertenecen.
Use el ID de ejecución lógica a través de los reintentos. Una identidad ausente
sigue siendo `None`. Nunca la sustituya por un ID de tarea, intento o sesión.
La [guía de identidad de Python](../polyglot/python.md#activity-identity) enlaza
el ejemplo de modo servicio mantenido por el SDK y define el comportamiento
de claims antiguos, sesiones, actividades locales preparadas, actividades
locales inline y contextos sin Server. Su recibo con el paquete publicado y
Server nativo solo demuestra identidad en reintentos ordinarios. El ID es
metadato público, no autoridad del claim, y no hace que un efecto externo ocurra
exactamente una vez. Mantenga la idempotencia del destino, claves distintas
para efectos diferentes y reconciliación de resultados.

## Qué debe ser idempotente en tu aplicación {#what-developers-must-make-idempotent}

No necesitas hacer idempotente la reproducción del workflow. El framework se
Expand Down
34 changes: 34 additions & 0 deletions i18n/es/docusaurus-plugin-content-docs/current/polyglot/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,40 @@ async def long_running_task(items: list) -> dict:
return {"processed": len(items)}
```

#### Identidad de la ejecución lógica de una actividad {#activity-identity}

Python SDK 2.15.0 y posteriores exponen el campo opcional de solo lectura
`activity.context().info.activity_execution_id`. Identifica una ejecución
lógica de actividad a través de sus reintentos. `info.workflow_id` e
`info.run_id` identifican la instancia de workflow y la ejecución a las que
pertenece. Use el ID de ejecución lógica como clave de idempotencia del
servicio externo. Los ID de tarea y de intento cambian al reintentar y no
deben sustituirlo.

Los ID de ejecución ausentes, no válidos o en blanco siguen siendo `None`,
también en claims antiguos. Las cadenas recibidas que no están en blanco
conservan su escritura exacta. Si una operación requiere esta clave, rechácela
antes del efecto externo cuando el ID no esté disponible. Las actividades
dirigidas a una sesión usan la identidad de su claim ordinario. Las actividades
locales preparadas usan el ID de ejecución de su recibo de admisión validado.
Las actividades locales inline no tienen un ID de ejecución admitido y exponen
`None`, aunque conservan los ID del workflow y de la ejecución padre. Los mocks
sin Server no crean identidad de actividad de Server.

Consulte el ejemplo de modo servicio en la [guía del SDK sobre el helper de claves de idempotencia y la identidad de actividad](https://python.durable-workflow.com/sdk-reference/#activity-execution-identity).
Asigne sufijos de operación estables a las distintas operaciones externas y
asegúrese de que el servicio de destino respeta la clave. Un ID de ejecución
es metadato público, no una prueba de un claim activo ni una autorización para
un efecto externo. Mantenga las credenciales, el fencing del intento actual
y la reconciliación de resultados. El [recibo de reintento ordinario con el paquete publicado](https://github.com/durable-workflow/.github/issues/211#issuecomment-6869562527)
vincula Python SDK 2.17.2 con Server nativo 3.9.2. Demuestra que los ID de
ejecución lógica de actividad, instancia de workflow y ejecución de workflow
se mantienen estables, mientras los ID de tarea y de intento son distintos
entre los intentos 1 y 2. El comportamiento local y de
sesión mantiene su alcance definido por separado. Consulte las
[garantías de ejecución](../constraints/execution-guarantees.md#service-activity-identity)
para el contrato de idempotencia compartido.

#### Política de reintentos recibida e intento original {#activity-retry-metadata}

Requiere Python SDK **2.12.0 o posterior**. `info = activity.context().info`
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 @@ -14,7 +14,7 @@
"configuration/publishing-config.md": "c757acd749c0d2696a6e19484249c9298dd15970ce0cf2ae0e6d2dfd82c8b6d6",
"constraints/activity-constraints.md": "5a953d0e95e750b6c02d1c72b72199fb3ff4687540cebc56aa3b216cf667bb05",
"constraints/constraints-summary.md": "fb48d01502388fc3821eae3790f470ed29cec91545420450f96fc77b84e589f1",
"constraints/execution-guarantees.md": "c24aaff70bfcf50366459ec698ced67adff1e02c1b0ca23c8178a13873037f5a",
"constraints/execution-guarantees.md": "9e53840c400b14186587714b32dd54dd780aaa68f2a132fc1e4e4d1f3eeadd0b",
"constraints/idempotent-vs-deterministic.md": "f7396f01a4111ce187e751b009c1efb96f5538e8a602006eed24f7b1d8f44adf",
"constraints/overview.md": "fd6c842c6c22d6f0df37a52de15ca74b34664f5ecd78af0c08b1e0cdb9a2be1f",
"constraints/structural-limits.md": "5c7b7f6c86c5ca547eb3f200400ceab3b589f32d83866914f44e3a5a7d81e964",
Expand Down Expand Up @@ -84,7 +84,7 @@
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
"polyglot/python.md": "82da06617fe24e70c5c89197d192a81430a282b788ef93afd3b3bcb690ba2a9f",
"polyglot/python.md": "57734052d6ffae8d660083626bf47fb7c392c492ab0581a8942401046bb25d38",
"polyglot/runtime-migration.md": "5a78713bb8cb74aea58f6d5d826400d968a405f69c6ff17fdf2f7decb1d14b71",
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "31950634b8ccdb5c288ba871cc7f816de6683c52bf738bfdc13fa7aa825c6335",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ final class ChargeCard extends Activity

Pour les activités Rust en mode service, le SDK **4.9.0 ou ultérieur** expose les valeurs initiales facultatives `activity_execution_id()`, `workflow_id()` (instance) et `run_id()` via `ActivityContext`. Utilisez l’ID logique d’activité entre les retries ; les champs absents du claim restent `None`, et un ID de tâche ou de tentative ne les remplace pas. La [recette du handler Rust](../polyglot/rust.md#activity-identity) dérive une clé externe et précise les limites des anciens Server, des activités locales et des tests sans Server. La clé exige toujours une API externe idempotente ou un registre durable des effets ; ces méthodes ne fournissent pas de checkpoints permettant une reprise.

Les activités Python en mode service exposent le champ facultatif en lecture
seule `activity.context().info.activity_execution_id`, avec `workflow_id` et
`run_id` pour l’instance de workflow et le run auxquels elles appartiennent.
Utilisez l’identifiant d’exécution logique à travers les nouvelles tentatives.
Une identité absente reste `None`. Ne la remplacez jamais par un identifiant
de tâche, de tentative ou de session. Le [guide d’identité Python](../polyglot/python.md#activity-identity)
renvoie à l’exemple en mode service du SDK et définit les anciens claims, les
sessions, les activités locales préparées, les activités locales inline et les
contextes sans Server. Son reçu avec paquet publié et Server natif prouve
uniquement l’identité des nouvelles tentatives ordinaires. L’identifiant est
une métadonnée publique, pas une autorité de claim, et ne garantit pas qu’un
effet externe se produise exactement une fois. Conservez l’idempotence du destinataire, des
clés distinctes pour des effets différents et la réconciliation des résultats.

## Effets que l’application doit rendre idempotents {#what-developers-must-make-idempotent}

Vous n’avez pas besoin de rendre la relecture du workflow elle-même idempotente. Le framework gère la relecture en reconstruisant l’état depuis l’historique validé.
Expand Down
Loading
Loading