Duplicate POST Writes Occur When HttpClient Retries After Timeout in Xamarin.Android
0 reputation · 08 Feb 2021, 15:18 UTC
0 reputation · 08 Feb 2021, 15:18 UTC
The goal is to configure Xamarin’s HttpClient so that a transient network timeout does not cause the same non‑idempotent POST to be sent twice, which would create duplicate records on the server. Xamarin’s HttpClientHandler provides no built‑in retry mechanism, so any custom retry logic must be added by the developer, but the framework does not supply a standard way to generate a unique request‑ID header that could be used for server‑side deduplication.
Constraints include the inability to rely on server‑side idempotency for POST operations, the need to preserve request semantics across process restarts, and the risk that a naïve retry implementation will re‑issue the exact same payload.
34775 reputation · 09 Feb 2021, 01:17 UTC
Do not auto-retry non-idempotent POST on timeout. Generate a stable, persistent request-ID per logical operation and attach it as X-Request-ID. Persist the ID and a monotonic counter in SharedPreferences so it survives app restarts and process kills. Retry POST only when the server explicitly signals it is safe to repeat, e.g., via a Retry-After header or a custom X-Retry-Permitted: true response. A server-side request-ID alone is not sufficient; maintain a client-side persisted record of sent IDs to avoid re-sending after a crash before a response is received.
On a transient network timeout the client assumes the request was not received and re-issues the same POST payload. If the server actually processed the first request, the retry creates a second record. This is a classic at-least-once vs at-most-once problem for non-idempotent methods.
{androidId}-{counter}. Increment and persist the counter before sending.Caution: ANDROID_ID can change on factory reset. The fallback UUID ensures continuity.
request.Headers.Add("X-Request-ID", requestId).Relying solely on a server-provided request-ID header is insufficient. The client may retry before any response is received, so the server never sees the first ID. A client-side persisted log of sent IDs ensures the same logical operation is not re-sent after a restart. Server-side deduplication using X-Request-ID is still required as a second line of defense.
Missing diagnostic detail that changes recommendation: does the server currently return any response body or status for a timed-out POST, or is the timeout purely client-side with zero bytes received? If the server returns a definitive 4xx/5xx before the timeout, the retry policy can be tightened further.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.