warren.retry_management
Retry management: the worker that stores soft-failed messages and republishes
them after their delay. A lease (for example MongoRetryLease) lets one
instance schedule at a time.
Classes
MongoRetryLease
classMongoRetryLease(client, *, database_name, collection_name)paramclientAsyncMongoClientparamdatabase_namestrparamcollection_namestrmethodacquire_or_renewasync (holder_id, now, expires_at) -> boolparamholder_idstrparamnowfloatparamexpires_atfloatRetryWorker
classRetryWorker(worker_name, *, retry_store, republish_publisher, message_key_func=None, scoping_enabled=False, lease=None, lease_ttl_seconds=30, clock=time.time, sleep=asyncio.sleep)Worker that manages retry scheduling for soft-failed messages.
Observes the observer exchange and acts only on soft-failure
envelopes. It ignores all other messages. For each envelope:
- Persists to store (durability).
- Schedules
asyncio.call_laterfor delayed republishing. - On timer: fetches message, republishes, deletes from store.
On startup (via schedule_pending), loads scheduling metadata for
persisted messages and reschedules remaining delays. With a lease, call
start to acquire ownership and poll for takeover. Standbys only persist.
Omitting the lease is intended for single-process use.
paramworker_namestrWorker identifier.
paramretry_storeDocumentStoreInterfacePersistent store for messages awaiting retry. Must use "retry_key" as its doc_id_field.
paramrepublish_publisherPublisherInterfacePublisher targeting the processing exchange.
parammessage_key_funcCallable[[dict], str] | None= NoneFunction to extract a composite key from a message dict. Defaults to building key from job_id/doc_id/part_idx using build_message_key.
paramscoping_enabledbool= FalsePrefix the retry key with the scope of the message (s:<scope>:) when the message has a valid scope.
paramleaseRetryLeaseInterface | None= NoneLease that lets one instance schedule and republish at a time. None means single-process use: this instance always schedules.
paramlease_ttl_secondsint= 30Lifetime in seconds of the lease.
paramclockCallable[[], float]= time.timeCurrent time in seconds. Replace it in tests.
paramsleepCallable[[float], Awaitable[None]]= asyncio.sleepDelay function for the lease loop. Replace it in tests.
Raises:
ValueError: If retry_store'sdoc_id_fieldis not"retry_key", or iflease_ttl_secondsis 0 or less.
attributeREQUIRED_DOC_ID_FIELDstr= 'retry_key'method__call__async (message) -> dict | NoneUnwrap soft-failure envelope, persist, and schedule.
parammessagedictSoft-failure wrapper with data_type: "soft-failure" and the failed message in data.
Returns
dict | NoneNone -- no downstream publish.
methodschedule_pendingasync () -> NoneLoad persisted retries and schedule timers.
Called on startup after setup. Queries the retry store for all persisted messages, computes remaining delay, and schedules timers. Messages past their fire time are republished immediately.
methodstartasync () -> NoneStart lease polling and recover persisted retries.
methodshutdownasync () -> NoneStop lease polling and cancel retries, leaving persisted work intact.
RetryWorkerRunner
classRetryWorkerRunner(config, worker_name, *, exchange, republish_exchange=None, retry_store=None, republish_publisher=None, consumer_manager_factory=None, message_key_func=None, infra=None)Runs a RetryWorker with its lifecycle hooks.
Creates infrastructure from RuntimeConfig and builds default
components in setup(). Inject custom components to override
defaults (e.g. for testing).
paramconfigRuntimeConfigruntime infrastructure configuration.
paramworker_namestrunique identifier for this retry worker.
paramexchangeRMQExchangeConfigThe observer exchange (observer_exchange(pipeline.exchange)).
paramrepublish_exchangeRMQExchangeConfig | None= NoneThe data exchange (pipeline.exchange). Defaults to exchange, which is correct for fanout and topic only.
paramretry_storeDocumentStoreInterface | None= Noneoptional override for the retry envelope store. Default: CachedDocumentStore wrapping MongoDB + Redis.
paramrepublish_publisherPublisherInterface | None= Noneoptional override for the exchange publisher. Default: a publisher of config.backend (from create_publisher) on republish_exchange, with ReplayRouter.
paramconsumer_manager_factoryConsumerManagerFactory | None= Noneoptional override for the consumer manager factory. Default: the consumer manager of config.backend (from create_consumer_manager) on the queue of the retry worker, bound to exchange.
parammessage_key_funcCallable[[dict], str] | None= Noneoptional function to extract a composite key from a message dict. Passed to RetryWorker.
paraminfraRuntimeInfra | None= Noneoptional shared infrastructure. When given, the runner uses it and does not close it; the caller owns its lifetime. Needed when several runners share one process (backend: memory).
methodsetupasync () -> NoneCreate infrastructure, build defaults, wire the worker.
- Create infrastructure (MongoDB, Redis, pubsub connection)
- Build default retry store, publisher, consumer factory for any components not injected
- Set up the republish publisher
- Create the RetryWorker
- Create and set up the consumer manager
- Schedule pending retries from the store
Protocols
RetryLeaseInterface
protocolRetryLeaseInterfacemethodacquire_or_renewasync (holder_id, now, expires_at) -> boolClaim an expired lease or extend this holder's lease.
paramholder_idstrparamnowfloatparamexpires_atfloatConstants
RETRY_WORKER_TYPE
constantRETRY_WORKER_TYPE: str = 'retry_worker'