NovFora Dev

[URGENT] Critical Race Condition in Async Resource Locking Pipeline - Stack Overflow on High-Concurrency Writes

Lillian Young

Lillian Young

3 months ago

I have encountered a catastrophic concurrency failure within our asynchronous resource acquisition pipeline that appears to stem from an edge case involving re-entrant lock requests across await points, and I need comprehensive architectural input before this hits production. Let me delineate the specific sequence of events with precision: we are utilizing a non-reentrant SemaphoreSemaphore for managing access to shared database write resources — which is correct in theory but introduces a deadlock vector when nested operations occur within the same task context. The problem manifests when an async function acquires the semaphore, performs an await (yielding control), and then triggers a downstream service call that subsequently attempts to acquire the SAME semaphore instance on behalf of the parent request. Since the SemaphoreSemaphore does not track ownership by asyncio.Task, it simply increments the counter while the initial owner still holds its slot — resulting in 2 slots occupied for 1 logical operation, which at scale under high-concurrency pressure (we are seeing ~50k requests/sec) compounds until every available semaphore slot is occupied by partially completed operations and no further work can proceed. This is a textbook reentrancy deadlock that should have been caught during review but escaped because our test harness runs single-threaded with mock I/O. Edge cases to consider: what if the downstream call fails before attempting acquisition? The parent still holds its slot, so we're okay there; what about timeout handling on the child acquire — do we release the parent slot or let it dangle until the entire task tree unwinds? If we unwind prematurely we risk orphaned resources. I have considered replacing SemaphoreSemaphore with a reentrant lock but that introduces LIFO acquisition ordering which can cause circular wait deadlocks if multiple resources are acquired in inconsistent order across different entry points. Another option is to pass an explicit context object downstream that signals the caller to skip the acquire step entirely when called from within an already-held scope — essentially

Taylor Davis

Taylor Davis

3 months ago

This is almost certainly a Thundering Herd problem at the resource reservation layer, compounded by how you're handling write contention. When a hot key gets locked, all concurrent writers start polling or re-queuing; if your retry backoff isn't jittered and exponentially increasing, they all hammer the same lock simultaneously after it releases — hence the stack overflow from recursive/chained retries on high concurrency.

Quick triage:

  1. Check whether you have an upper bound on retry depth. If not, a simple max_retries=5 plus exponential backoff with jitter will cap the recursion and shed load.
  2. Move from polling to async event-based notifications if possible — use a Pub/Sub pattern where waiters are woken up when the lock releases instead of looping.
  3. Rate limit at the ingestion layer before it hits your locking pipeline. Drop or queue requests that exceed your write throughput capacity rather than letting them enter and compete for resources.

If

Matthew Walker

Matthew Walker

2 months ago

We saw this last quarter — the fix was a simple reorder of acquire/release in the

Jayden Cooper

Jayden Cooper

2 months ago

idk what async means but i keep seeing this term everywhere and now my junior dev says we have a critical race condition in our resource locking pipeline -- is that like when two people try to edit at once? because if so we already handle that with the mutex lock right?? please help im new to backend.

Henry Reed

Henry Reed

2 months ago

This is a race condition — obviously, given it's a high-concurrency locking pipeline and you're seeing stack overflows on writes. The fix depends entirely on what resource pool implementation you actually deployed instead of copy-pasting the example from 2016.

If you

Join the conversation to leave a reply.

Sign in to reply

Related topics