Interview question
Implement an idempotent retryable Celery provider task
Builds a Celery task that survives timeout ambiguity, retries temporary failures, and records one durable business outcome.
TL;DR
Builds a Celery task that survives timeout ambiguity, retries temporary failures, and records one durable business outcome.
Celery bound tasks, selective retries, backoff, stable provider idempotency keys, database state transitions, and reconciliation.
Practice the problem like a real interview: restate, reason, implement, and test.
Implement charge_payment(operation_id). The operation row already exists with a stable provider idempotency key. Claim pending work, call the provider with timeouts, retry only temporary failures with bounded exponential backoff, and mark success once. A timeout may happen after the provider accepted the charge, so every retry must reuse the same key.
Move to the linked follow-up, next path step, prerequisite, or deeper variant.
Practice the next layer of the same subject.
first call times out after provider accepts -> retry uses same provider key
provider returns same charge -> operation becomes succeeded once
invalid card -> terminal failure, no retry
self.retry; reconcile ambiguous exhaustion.from celery import shared_task
@shared_task(bind=True, acks_late=True, max_retries=5)
def charge_payment(self, operation_id: str) -> None:
with session_factory() as session:
operation = load_operation_for_update(session, operation_id)
if operation.status == "succeeded":
return
if operation.status == "failed":
raise PermanentPaymentFailure(operation.failure_code)
provider_key = operation.provider_idempotency_key
try:
result = provider.charge(
amount=operation.amount,
idempotency_key=provider_key,
timeout=(2.0, 8.0),
)
except TemporaryProviderError as exc:
record_retry_attempt(operation_id, type(exc).__name__)
raise self.retry(exc=exc, countdown=min(60, 2 ** self.request.retries))
except PermanentProviderError as exc:
mark_failed(operation_id, exc.safe_code)
return
mark_succeeded_once(operation_id, result.charge_id)
Each attempt performs bounded indexed state reads/writes plus one provider call. Retry cost is bounded by the configured attempt budget.
Spot a weak answer, missing edge case, or clearer explanation? Send it in.
Say thanks with a standalone, one-time $5 contribution. No account required.