Retry policies, backoff execution, and idempotency gates for AI execution systems
Project description
nodus-retry
Retry policies, backoff execution, and idempotency gates for AI execution systems.
Named retry policies for each execution type, sync and async execution with
exponential backoff, non-retryable error classification, and an EXACTLY_ONCE
idempotency gate via EffectStore. No required external dependencies — pure stdlib.
Note:
nodus-retryis a required dependency ofnodus-lang>=4.1.0. TheEffectStoreandInMemoryEffectStoreare also available fromnodus-langscripts viastd:effects.
Status: v0.1.0 — prepared, not yet published.
Install
pip install nodus-retry
What it provides
| Component | Purpose |
|---|---|
RetryPolicy |
Immutable retry configuration (max_attempts, backoff, exponential, guarantee) |
| Named policies | FLOW_NODE_DEFAULT, AGENT_LOW_MEDIUM, AGENT_HIGH_RISK, ASYNC_JOB_DEFAULT, NODUS_SCHEDULED_DEFAULT, NO_RETRY |
resolve_retry_policy |
Look up policy by execution_type + risk_level string |
execute_with_retry |
Run a sync callable under a RetryPolicy |
execute_with_retry_async |
Run an async callable under a RetryPolicy |
is_retryable_error |
Classify error strings as retryable or not |
InMemoryEffectStore |
Thread-safe EXACTLY_ONCE idempotency gate |
compute_action_id |
SHA-256 hash of (action_type, payload, scope) |
RetryPolicy
from nodus_retry import RetryPolicy
policy = RetryPolicy(
max_attempts=3,
backoff_ms=200,
exponential_backoff=True, # 200ms, 400ms, 800ms
high_risk_immediate_fail=False,
execution_guarantee="AT_LEAST_ONCE", # or "EXACTLY_ONCE"
)
Named policies
from nodus_retry import (
FLOW_NODE_DEFAULT, # 3 attempts, 500ms exponential, AT_LEAST_ONCE
AGENT_LOW_MEDIUM, # 3 attempts, 200ms exponential, AT_LEAST_ONCE
AGENT_HIGH_RISK, # 1 attempt, high_risk_immediate_fail=True
ASYNC_JOB_DEFAULT, # 5 attempts, 1000ms exponential
NODUS_SCHEDULED_DEFAULT, # 3 attempts, 300ms exponential
NO_RETRY, # max_attempts=1
)
Resolve by name
from nodus_retry import resolve_retry_policy
policy = resolve_retry_policy("FLOW_NODE_DEFAULT")
policy = resolve_retry_policy("AGENT_LOW_MEDIUM")
Execution
from nodus_retry import execute_with_retry, execute_with_retry_async, FLOW_NODE_DEFAULT
# Sync
result = execute_with_retry(
lambda: call_external_api(),
policy=FLOW_NODE_DEFAULT,
)
# Async
result = await execute_with_retry_async(
my_async_fn,
policy=AGENT_LOW_MEDIUM,
)
Retries on any exception unless is_retryable_error classifies the error
string as non-retryable (e.g. auth errors, validation errors).
Error classification
from nodus_retry import is_retryable_error
is_retryable_error("connection timeout") # True
is_retryable_error("rate limit exceeded") # True
is_retryable_error("unauthorized") # False
is_retryable_error("invalid input") # False
EffectStore — EXACTLY_ONCE idempotency
from nodus_retry import InMemoryEffectStore, compute_action_id
store = InMemoryEffectStore()
# Compute a deterministic action ID
action_id = compute_action_id("memory.write", {"key": "k", "value": "v"}, scope="run-001")
# Check before executing
already_done, cached = store.resolve(action_id)
if already_done:
return cached # idempotent return
store.pending(action_id, input_hash="h")
try:
result = do_the_work()
store.complete(action_id, "success", result)
return result
except Exception:
store.complete(action_id, "failed", None)
raise
EffectStore is a @runtime_checkable Protocol — any class with resolve,
pending, and complete methods satisfies it.
Design
- No required dependencies. Pure stdlib (
hashlib,json,threading,asyncio,dataclasses). nodus-lang>=4.1.0requires this package.InMemoryEffectStoreis wired into the VM asself.effect_storeand exposed viastd:effects.
Development
pip install -e ".[dev]"
pytest tests/ -q
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nodus_retry-0.1.0.tar.gz.
File metadata
- Download URL: nodus_retry-0.1.0.tar.gz
- Upload date:
- Size: 10.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76ddcf6ae36d85ba177f907b0cab3252815b81d999eed5b9d63900b3d9f2cd5d
|
|
| MD5 |
a4d7dcf46526e6fd606da178f7d8f90d
|
|
| BLAKE2b-256 |
121741639518016b6d9cacdbc6eb17669a38a87f89995dd0580a19ba2eb13b5d
|
File details
Details for the file nodus_retry-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nodus_retry-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0aed693d13fc43c9f4d0f298a27665d895b69f24e8546f1acfea1711649e47a
|
|
| MD5 |
82452a92c20634977733962d3e6db40e
|
|
| BLAKE2b-256 |
6ff8710b5d330001749a1ad6fa0dd1ebac9221f168f38d40b7107362662c45a4
|