agent foundation
This commit is contained in:
@@ -98,6 +98,9 @@ class RateLimiterService
|
||||
$nowTs = time();
|
||||
$nowSql = gmdate('Y-m-d H:i:s', $nowTs);
|
||||
|
||||
// Two-attempt loop handles a creation race: if two requests arrive simultaneously for a
|
||||
// new subject, both may find no row and try to INSERT. The second INSERT fails (unique key),
|
||||
// so we retry once and the second attempt reads the now-existing row.
|
||||
for ($attempt = 0; $attempt < 2; $attempt++) {
|
||||
$row = $this->rateLimitRepository->findByScopeAndHash($normalized['scope'], $normalized['subject_hash']);
|
||||
|
||||
@@ -136,6 +139,7 @@ class RateLimiterService
|
||||
}
|
||||
|
||||
$windowStartedTs = $this->parseTimestamp((string) ($row['window_started_at'] ?? ''));
|
||||
// Sliding window expired — reset the window start and hit count.
|
||||
if ($windowStartedTs === null || ($windowStartedTs + $windowSeconds) <= $nowTs) {
|
||||
$windowStartedTs = $nowTs;
|
||||
$hits = 0;
|
||||
@@ -189,6 +193,7 @@ class RateLimiterService
|
||||
$scope = substr($scope, 0, 64);
|
||||
}
|
||||
|
||||
// Hash the subject (e.g. email or IP) so PII is never stored in the rate limit table.
|
||||
return [
|
||||
'scope' => $scope,
|
||||
'subject_hash' => hash(self::HASH_ALGO, $subject),
|
||||
|
||||
Reference in New Issue
Block a user