Send Requests in Batches of Five and Retry Failures After a Per-Request Delay
Company: Decagon
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
You are given a list of requests and must deliver every one of them to a dummy API. The API is batch-oriented: a single call carries at most 5 requests, passed together in the request body.
### Clarifying Questions
- What does the dummy API look like: a Python function or an HTTP endpoint, and what does its response contain? Is success or failure reported per request or for the whole batch?
- Is the call synchronous? May several batches be in flight at once, or is one call at a time expected?
- Must results be returned to the caller, and in the original order of the requests?
- Is there a limit on how many times a request may be retried, or an overall deadline?
### Part 1 — Send all requests in batches of at most five
Write a function that takes the list of requests and sends all of them to the API, using as few calls as the limit of five requests per call allows.
```hint Keep batching separate
Treat grouping requests into batches as its own small step, and keep track of which response belongs to which request; both pieces get reused once retries arrive.
```
#### What This Part Should Cover
- Correct chunking, including a final partial batch, with no request skipped or sent twice.
- Mapping each response back to the request that produced it.
- A thin, swappable interface to the API so the logic can be tested with a fake.
### Part 2 — Retry failed requests after a delay
Some requests fail. For a failed request, the response gives a number of seconds that must pass before that request may be retried. Adjust your solution so that every failed request is retried, never earlier than its delay allows, while the other requests keep flowing.
```hint Order by readiness
Each failed request now has its own earliest retry time. Think about which structure hands you the next request to become ready, and what the loop should do while nothing is ready yet.
```
#### Clarifying Questions for this Part
- Is the delay measured from the moment the response is received?
- May a retried request share a batch with requests that have not been sent yet?
- Can a request fail repeatedly, and what should be reported if it never succeeds?
#### What This Part Should Cover
- Recording each failed request's earliest retry time from the current time, and sending it only after that time has passed.
- Filling batches with every request that is ready, and waiting efficiently when none is: no busy loop and no blocking sleep per failure.
- Termination and failure handling: retry limits, whole-call failures such as timeouts, and a final report of what never succeeded.
### What a Strong Answer Covers
- Correctness: every request is delivered or reported as failed, none is sent early, lost or duplicated by the client's own logic.
- Efficient use of the batch limit, with a stated policy for combining retries with fresh requests.
- Time handling with a monotonic clock, and code that can be tested without really sleeping.
- Clear separation between batching, scheduling and the API client.
- Complexity in terms of the number of requests and retries.
### Follow-up Questions
- If the API allows several calls in flight at once, how would you change the design?
- How would you handle a whole-client rate limit, where the API rejects every call for some seconds, rather than per-request delays?
- A request may have succeeded on the server even though its response was lost in a timeout. How do you avoid applying it twice?
- How would you test this code deterministically without real waiting?
Overview: A practical coding exercise: send a list of requests to an API that accepts at most five per call, then retry failed requests only after the per-request delay returned by the API. It tests batching, retry scheduling with timestamps, waiting without busy loops and clean handling of partial failures.