MailboxProcessor retry policy with idempotency key for external writes
0 reputation · 30 Jan 2020, 14:46 UTC
0 reputation · 30 Jan 2020, 14:46 UTC
Goal: configure an FSharp.Core MailboxProcessor<T> agent to retry a failed message after a transient fault while ensuring the corresponding external write is not duplicated. The agent serializes messages on a single in-process thread, so retried attempts do not overlap, but the mailbox itself is in-memory and is discarded on restart.
Constraint: MailboxProcessor exposes no built-in retry policy, persistence, replay queue, or idempotency-key parameter on its constructors or Post, PostAndAsync, and Scan methods. The application must supply deduplication tokens and validate them against an external store, but it is unclear where token generation and store checks should sit relative to the agent's receive loop without blocking unrelated messages.
Version assumption: current FSharp.Core MailboxProcessor API has no durable retry configuration.
Specific questions:
34775 reputation · 30 Jan 2020, 15:16 UTC
MailboxProcessor has no built-in retry, persistence, replay queue or idempotency support. The agent is single-threaded and in-memory, so any retry state lives only while the process is up.
Generate the idempotency key by the caller before posting and embed it in the message. Confirmed: MailboxProcessor constructors and Post/PostAndAsync/Scan do not accept an idempotency parameter. Likely: caller-side generation keeps token lifecycle outside the agent, survives agent restarts, and allows the caller to decide uniqueness scope. Agent-side generation is possible but ties the key to in-memory agent lifetime and makes re-post after a crash ambiguous.
Do not perform synchronous external store calls in the receive loop. Confirmed: the receive loop runs on one thread, so a blocking call stalls all messages. Likely safe pattern:
Confirmed: MailboxProcessor state and its mailbox are purely in-memory. On process restart all pending messages, scheduled retries and in-memory token state are lost. Deduplication tokens that were only stored in the agent are lost. Only tokens and retry intent persisted by the caller or in the external store survive. After restart the agent starts empty; you must re-hydrate work from an external durable queue if at-least-once delivery is required.
Confirmed: No built-in retry/persistence/idempotency in FSharp.Core MailboxProcessor API. Single in-process serialization. Mailbox discarded on restart.
Likely, for review: Caller-side key generation and async non-blocking retry via delayed re-post is the practical pattern. Verification needed for your external store consistency model to ensure a retry with the same key is safely ignored.
Missing diagnostic detail that changes recommendation: can the caller durably persist the message + key before posting, and is the external write operation already idempotent by key? If not, agent-side key generation and an external durable outbox are required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.