mirror of
https://github.com/lukaszraczylo/graphql-monitoring-proxy.git
synced 2026-06-05 23:03:48 +00:00
Race condition in parseGraphQLQuery result pooling
Under high concurrency, the sync.Pool pattern was creating a race condition where the same result pointer was being reused by multiple concurrent requests. The bug: - parseGraphQLQuery() returns a pointer to 'res' from the pool - The defer statement returns 'res' back to the pool on function exit - While the caller is still using the returned pointer, another concurrent request could get the SAME pointer from the pool and modify it This caused mutations to randomly get the wrong activeEndpoint value: - Request A: mutation parsed → activeEndpoint set to :8080 (write) - Request A: returns pointer to result - Request A: defer runs → result returned to pool - Request B: gets SAME pointer from pool - Request B: query parsed → activeEndpoint overwritten to :8088 (read-only) - Request A: still holding pointer, now sees :8088 instead of :8080! - Result: mutation routed to read-only endpoint → database write failure The fix: Create a copy of the result before returning, so the pooled object can be safely reused without affecting the returned value.
This commit is contained in:
+4
-1
@@ -401,7 +401,10 @@ func parseGraphQLQuery(c *fiber.Ctx) *parseGraphQLQueryResult {
|
|||||||
cfg.Monitoring.IncrementFloat(libpack_monitoring.MetricsGraphQLParsingTime, nil, parseTime)
|
cfg.Monitoring.IncrementFloat(libpack_monitoring.MetricsGraphQLParsingTime, nil, parseTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
// Create a copy to return, since the original will be returned to the pool
|
||||||
|
// This prevents race conditions where concurrent requests could modify the same result
|
||||||
|
result := *res
|
||||||
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
// processDirectives extracts caching directives from the operation
|
// processDirectives extracts caching directives from the operation
|
||||||
|
|||||||
Reference in New Issue
Block a user