AI-narrated article. Prose is preserved with pronunciation adjustments; code and image cues refer to the written article.
AI-Era Coding Interviews: Explain Who Owns the Shared Task
This is the AI-narrated article. The prose follows the written post; pronunciation is adjusted, and code and images are announced separately.
Use an asyncio single-flight problem to explain invariants, test cancellation and debug a plausible generated implementation without performance claims.
TL;DR: AI-assisted coding interviews still require the candidate to own the contract and evidence. This worked asyncio problem shares one load per authorized key while isolating waiter cancellation, bounding registered flights and retiring failures. Explain the default-loop assumption, key-sharing boundary, task context and owner-controlled shutdown before accepting a draft. A complete implementation and runnable cancellation test accompany a focused local correctness suite and a deliberately broken direct-await regression. These checks demonstrate specified code behavior under Python 3.12, not AI productivity, distributed coordination, backend safety or production performance.
An AI-assisted coding interview can produce a convincing implementation before the candidate has explained its ownership model. That becomes dangerous when the problem involves cancellation, concurrency or permissions: the happy path can pass while one caller destroys another caller's work.
Use a concrete platform problem. Concurrent requests for the same authorized resource should share one asynchronous load, while a caller disconnecting must not cancel the load for other callers. The worked solution below is an interview-sized single-flight primitive, with executed correctness tests and a deliberately broken cancellation variant. Those checks are evidence about this code, not measurements of AI productivity or production performance.
Explain the contract before accepting generated code
Start by confirming the interview's tool policy, then state the behavior you intend to implement. Here, keys contain a trusted authorization realm and resource identifier. A completed result is not cached. A failed load is retired so a later call can retry. A bounded registry admits new keys only while capacity is available, but callers joining an existing key remain allowed. The service owner closes outstanding loads during shutdown.
This is one process and one default asyncio event loop, not a distributed duplicate-suppression guarantee. It is not thread-safe. Admission counts registered flights until retirement, not all application requests or a global backend concurrency limit. Dictionary lookup is normally constant time; memory is bounded by the registered-key limit plus tasks and waiting callers outside that registry.
Worked interview answer: "Why not just put every request behind a lock?" That serializes independent resources and can unnecessarily couple cancellation. Sharing one task per key preserves independent work while making same-key ownership explicit. A lock alone does not specify who may cancel the shared task.
Image. One shared load has independent waiter cancellation and owner-controlled shutdown
Implement task ownership, not just deduplication
Use Python 3.12; the actual local run used 3.12.14 and only the standard library. Save this complete implementation as singleflight.py. Construct it inside the event loop that will own it. Custom task factories are intentionally outside this version's contract.
Code example. Refer to the written article for the complete code.
Registry lookup, admission and insertion contain no suspension point. Within the stated loop confinement, another coroutine cannot interleave that synchronous section. The strong task reference keeps shared work owned after a waiter leaves. shield prevents cancellation of that waiter from propagating to the shared task; the waiter itself still receives CancelledError. Tasks and shielding
The retirement callback checks task identity before removing a key. Otherwise, an old completion callback could delete a newer flight for the same key. Reading the completed task's exception avoids an unobserved-failure warning when nobody remains to await it; it does not convert a failure into success for surviving waiters. This distinction is part of the explanation, not a comment to trust without review. Future completion and exceptions
aclose belongs to one lifecycle owner, which should await it without cancelling the shutdown coroutine. Loaders must cooperate with cancellation and release resources in finally. This implementation does not forcibly terminate an uncooperative loader or guarantee a shutdown deadline. Cancellation behavior
Write the test that exposes the ownership bug
Save this runnable test_singleflight.py beside the implementation. Events coordinate the test; elapsed time is not an assertion. A single scheduler yield lets the second waiter join before the first is cancelled. IsolatedAsyncioTestCase supplies an isolated loop for each test. Async test support
Code example. Refer to the written article for the complete code.
Run python -m unittest -v test_singleflight.py. The accompanying verification assets also contain focused tests for coalescing, failure eviction/retry, capacity rejection with same-key joining, realm separation and owner shutdown. The complete local suite passed. These are correctness checks, not cloud experiments, latency benchmarks or evidence that a real backend is safe.
For cleanup, retain the source/tests and remove their local __pycache__ if desired. No deployment or remote resource was created.
Debug a plausible first draft, then explain the minimal repair
Question: "The candidate's implementation passes two successful requests. Why reject it?" Ask how cancellation propagates. A plausible first draft ends get with return await task. If one waiter awaiting that task is cancelled, it can cancel the shared task and disrupt another waiter. Two successful calls do not test that property.
The local regression replaced only the shielded await with the direct await in an isolated copy. The cancellation test failed with CancelledError at the surviving waiter's await. Restoring asyncio.shield made the test pass. No timing or traffic measurement is inferred from that result. Preserve the failing trace and identify the ownership rule it contradicts rather than rewriting the entire implementation.
Worked answer: "What does shielding fail to solve?" It does not stop an explicit owner cancellation, a loader failure or an event-loop shutdown. It also does not decide whether work should continue after every waiter leaves. Here, work remains registered until completion or owner shutdown. For expensive operations, another design may track waiter counts and cancel orphaned work; that changes the contract and needs additional race tests.
Separate a correct primitive from a safe platform integration
The key must represent the complete sharing boundary. Tenant plus resource can be insufficient when users in the same tenant have different entitlements or request parameters. Authenticate and authorize before constructing the key; include any permission scope or result-shaping input that changes whether sharing is allowed. Deduplication is not an authorization check.
create_task normally copies the first caller's context. A loader that implicitly reads caller credentials or tracing context can therefore inherit the first caller's identity while serving other waiters. Bind backend authority explicitly and decide how operation-level telemetry represents shared work. Do not use an ambient principal as a substitute for the validated sharing boundary. Task context, context variables
Capacity rejection also needs an application policy: fail fast, retry with bounded backoff or use another queue. Putting an unbounded queue around a bounded registry simply moves the memory problem. Distinguish admitted flights, waiting callers and backend resource limits in the explanation.
Show what you understand when AI supplies the draft
State which parts came from a tool under the interview's rules, then own the contract, code review and evidence. Explain why each adversarial test exists, reproduce a failure, and say which assumption limits the result. Do not claim a generated implementation is correct because it looks familiar or because another tool approved it.
What should the interviewer learn from this exercise? Whether the candidate can reason about ownership, maintain a falsifiable explanation and make a small verified repair.
What did the local tests prove? The specified behaviors of this loop-confined implementation, under the tested runtime and fixtures.
What remains unproven? Distributed coordination, real backend cancellation/resource cleanup, authorization integration, load behavior and production readiness.