fix(phase-16): forward X-Forwarded-For from EventProxyController so the API rate limiter partitions per client IP
Proxy chains any inbound XFF with the connection IP before relaying upstream; UseForwardedHeaders resolves it to the limiter's partition key. Documents the EventRepository first-play counter race (unique index is the backstop).
This commit is contained in:
@@ -102,6 +102,12 @@ public class EventRepository
|
||||
// Bump the matching bucket column on the track's counter row, creating the row on first play. The
|
||||
// row is added to the change tracker but not saved here — the caller's SaveChanges/commit persists
|
||||
// it inside the same transaction as the event append.
|
||||
//
|
||||
// Race note: two concurrent first-plays of the same track can both reach this method, find no
|
||||
// counter row, and both Add a new PlayCounter. The second SaveChanges will hit the unique index on
|
||||
// (track_id) and throw, causing the outer transaction to roll back and the event to be dropped —
|
||||
// no crash, no counter corruption. At the expected play volume this is an acceptable loss; the
|
||||
// unique index is the integrity backstop.
|
||||
private async Task BumpCounterAsync(long trackId, PlayBucket bucket, CancellationToken ct)
|
||||
{
|
||||
var counter = await _context.PlayCounters.FirstOrDefaultAsync(c => c.TrackId == trackId, ct);
|
||||
|
||||
Reference in New Issue
Block a user