Singleflight & Locks
Herd enforces strict session affinity even under heavy concurrent load. To prevent "thundering herd" issues, it utilizes a lightweight singleflight mechanism.
💥 The Race Condition
If two or more concurrent HTTP requests for sessionID = "user-123" arrive at the Pool at the exact same millisecond, a naive implementation might:
1. See that no worker is pinned to user-123.
2. Pop a free worker W1 from the pool.
3. Pop a free worker W2 from the pool for the second request.
4. Pin BOTH workers to the same session ID!
This breaks the core invariant: 1 Session ID → 1 Worker.
🛡️ The Solution: Channel Broadcast
Herd maintains an inflight map of channels (map[string]chan struct{}) to serialize acquisitions for the same session ID.
The Lifecycle
- Check Phase:
Pool.Acquirefirst checks if the session ID exists in thesessionsmap. If it does, it returns immediately (Fast Path). - Lock Phase: If it doesn't exist, it checks the
inflightmap:- If no inflight channel exists:
- The goroutine creates a channel
ch := make(chan struct{})and adds it to theinflightmap. - It proceeds to pop a worker from the
availablelist and pins it to the session. - Finally, it closes the channel
close(ch)and removes it frominflight.
- The goroutine creates a channel
- If an inflight channel DOES exist:
- The goroutine does not fetch a worker.
- It waits on the channel:
<-ch. - Once the channel is closed, it knows the first goroutine completed the workspace binding.
- It fetches the newly pinned worker from the
sessionsmap and continues.
- If no inflight channel exists:
This mechanism ensures that only the first request incurs the overhead of worker allocation or validation, while backlogs are queued smoothly with zero wasted resources.