Skip to content

Commit c1c4d45

Browse files
committed
wip
1 parent 38ab03c commit c1c4d45

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/Illuminate/Cache/ArrayStore.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function get($key)
5757

5858
$expiresAt = $item['expiresAt'] ?? 0;
5959

60-
if ($expiresAt !== 0 && $this->currentTime() > $expiresAt) {
60+
if ($expiresAt !== 0 && (now()->getPreciseTimestamp(3) / 1000) >= $expiresAt) {
6161
$this->forget($key);
6262

6363
return;
@@ -181,14 +181,14 @@ protected function calculateExpiration($seconds)
181181
}
182182

183183
/**
184-
* Get the UNIX timestamp for the given number of seconds.
184+
* Get the UNIX timestamp, with milliseconds, for the given number of seconds in the future.
185185
*
186186
* @param int $seconds
187-
* @return int
187+
* @return float
188188
*/
189189
protected function toTimestamp($seconds)
190190
{
191-
return $seconds > 0 ? $this->availableAt($seconds) : 0;
191+
return $seconds > 0 ? (now()->getPreciseTimestamp(3) / 1000) + $seconds : 0;
192192
}
193193

194194
/**

tests/Cache/CacheArrayStoreTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ public function testItemsCanBeSetAndRetrieved()
2424
$this->assertSame('bar', $store->get('foo'));
2525
}
2626

27+
public function testCacheTtl(): void
28+
{
29+
$store = new ArrayStore();
30+
31+
Carbon::setTestNow('2000-01-01 00:00:00.500'); // 500 milliseconds past
32+
$store->put('hello', 'world', 1);
33+
34+
Carbon::setTestNow('2000-01-01 00:00:01.499'); // progress 0.999 seconds
35+
$this->assertSame('world', $store->get('hello'));
36+
37+
Carbon::setTestNow('2000-01-01 00:00:01.500'); // progress 0.001 seconds. 1 second since putting into cache.
38+
$this->assertNull($store->get('hello'));
39+
}
40+
2741
public function testMultipleItemsCanBeSetAndRetrieved()
2842
{
2943
$store = new ArrayStore;

tests/Integration/Cache/RedisStoreTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
66
use Illuminate\Support\Facades\Cache;
7+
use Illuminate\Support\Facades\Config;
8+
use Illuminate\Support\Facades\Redis;
9+
use Illuminate\Support\Sleep;
710
use Orchestra\Testbench\TestCase;
811

912
class RedisStoreTest extends TestCase
@@ -24,6 +27,35 @@ protected function tearDown(): void
2427
$this->tearDownRedis();
2528
}
2629

30+
public function testCacheTtl(): void
31+
{
32+
while (true) {
33+
$store = Cache::store('redis');
34+
$store->clear();
35+
36+
while (((microtime(true)) - time()) > 0.5 && (microtime(true) - time()) < 0.6) {
37+
//
38+
}
39+
40+
$store->put('hello', 'world', 1);
41+
$putAt = microtime(true);
42+
43+
Sleep::for(600)->milliseconds();
44+
$this->assertTrue((microtime(true) - $putAt) < 1);
45+
$this->assertSame('world', $store->get('hello'));
46+
47+
// Although this key expires after exactly 1 second, Redis has a
48+
// 0-1 millisecond error rate on expiring keys (as of Redis 2.6) so
49+
// for a non-flakey test we need to account for the millisecond.
50+
// see: https://redis.io/commands/expire/
51+
while ((microtime(true) - $putAt) < 1.001) {
52+
//
53+
}
54+
55+
$this->assertNull($store->get('hello'));
56+
}
57+
}
58+
2759
public function testItCanStoreInfinite()
2860
{
2961
Cache::store('redis')->clear();

0 commit comments

Comments
 (0)