Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3a72990

Browse filesBrowse files
Seldaeknicolas-grekas
authored andcommitted
[RateLimiter] Always store SlidingWindows with an expiration set
1 parent ed9f973 commit 3a72990
Copy full SHA for 3a72990

File tree

Expand file treeCollapse file tree

2 files changed

+25
-24
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+25
-24
lines changed

‎src/Symfony/Component/RateLimiter/Policy/SlidingWindow.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/RateLimiter/Policy/SlidingWindow.php
+24-23Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@ final class SlidingWindow implements LimiterStateInterface
4343
*/
4444
private $windowEndAt;
4545

46-
/**
47-
* @var bool true if this window has been cached
48-
*/
49-
private $cached = true;
50-
5146
public function __construct(string $id, int $intervalInSeconds)
5247
{
5348
if ($intervalInSeconds < 1) {
@@ -56,7 +51,6 @@ public function __construct(string $id, int $intervalInSeconds)
5651
$this->id = $id;
5752
$this->intervalInSeconds = $intervalInSeconds;
5853
$this->windowEndAt = microtime(true) + $intervalInSeconds;
59-
$this->cached = false;
6054
}
6155

6256
public static function createFromPreviousWindow(self $window, int $intervalInSeconds): self
@@ -72,31 +66,17 @@ public static function createFromPreviousWindow(self $window, int $intervalInSec
7266
return $new;
7367
}
7468

75-
/**
76-
* @internal
77-
*/
78-
public function __sleep(): array
79-
{
80-
// $cached is not serialized, it should only be set
81-
// upon first creation of the window.
82-
return ['id', 'hitCount', 'intervalInSeconds', 'hitCountForLastWindow', 'windowEndAt'];
83-
}
84-
8569
public function getId(): string
8670
{
8771
return $this->id;
8872
}
8973

9074
/**
91-
* Store for the rest of this time frame and next.
75+
* Returns the remaining of this timeframe and the next one.
9276
*/
93-
public function getExpirationTime(): ?int
77+
public function getExpirationTime(): int
9478
{
95-
if ($this->cached) {
96-
return null;
97-
}
98-
99-
return 2 * $this->intervalInSeconds;
79+
return $this->windowEndAt + $this->intervalInSeconds - microtime(true);
10080
}
10181

10282
public function isExpired(): bool
@@ -124,4 +104,25 @@ public function getRetryAfter(): \DateTimeImmutable
124104
{
125105
return \DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', $this->windowEndAt));
126106
}
107+
108+
/**
109+
* @internal
110+
*/
111+
public function __serialize(): array
112+
{
113+
return [
114+
pack('NNN', $this->hitCount, $this->hitCountForLastWindow, $this->intervalInSeconds).$this->id => $this->windowEndAt,
115+
];
116+
}
117+
/**
118+
*
119+
* @internal
120+
*/
121+
public function __unserialize(array $data): void
122+
{
123+
$pack = key($data);
124+
$this->windowEndAt = $data[$pack];
125+
['a' => $this->hitCount, 'b' => $this->hitCountForLastWindow, 'c' => $this->intervalInSeconds] = unpack('Na/Nb/Nc', $pack);
126+
$this->id = substr($pack, 3);
127+
}
127128
}

‎src/Symfony/Component/RateLimiter/Tests/Policy/SlidingWindowTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/RateLimiter/Tests/Policy/SlidingWindowTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function testGetExpirationTime()
2929

3030
$data = serialize($window);
3131
$cachedWindow = unserialize($data);
32-
$this->assertNull($cachedWindow->getExpirationTime());
32+
$this->assertSame(2 * 10, $cachedWindow->getExpirationTime());
3333

3434
$new = SlidingWindow::createFromPreviousWindow($cachedWindow, 15);
3535
$this->assertSame(2 * 15, $new->getExpirationTime());

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.