Skip to content

Commit

Permalink
RedisStore improvement - don't open transaction unless all values are…
Browse files Browse the repository at this point in the history
… serialaizable (#47193)

* Create failing test case

* copy files from martinssipenko:psr6-redis-failure

* before inserting records serialize them

* change test case

* php style change

* fix expectation

* bump

* Update RedisStore.php

---------

Co-authored-by: Martins Sipenko <martins.sipenko@gmail.com>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
3 people committed May 24, 2023
1 parent 5dd3717 commit 9698de4
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/Illuminate/Cache/RedisStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,20 @@ public function put($key, $value, $seconds)
*/
public function putMany(array $values, $seconds)
{
$serializedValues = [];

foreach ($values as $key => $value) {
$serializedValues[$this->prefix.$key] = $this->serialize($value);
}

$this->connection()->multi();

$manyResult = null;

foreach ($values as $key => $value) {
$result = $this->put($key, $value, $seconds);
foreach ($serializedValues as $key => $value) {
$result = (bool) $this->connection()->setex(
$key, (int) max(1, $seconds), $value
);

$manyResult = is_null($manyResult) ? $result : $result && $manyResult;
}
Expand Down
13 changes: 13 additions & 0 deletions tests/Integration/Cache/Fixtures/Unserializable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Illuminate\Tests\Integration\Cache\Fixtures;

use Exception;

class Unserializable
{
public function __sleep()
{
throw new Exception('Not serializable');
}
}
58 changes: 58 additions & 0 deletions tests/Integration/Cache/Psr6RedisTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Illuminate\Tests\Integration\Cache;

use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
use Illuminate\Support\Facades\Cache;
use Illuminate\Tests\Integration\Cache\Fixtures\Unserializable;
use Orchestra\Testbench\TestCase;

class Psr6RedisTest extends TestCase
{
use InteractsWithRedis;

protected function setUp(): void
{
parent::setUp();

$this->setUpRedis();
}

protected function tearDown(): void
{
parent::tearDown();

$this->tearDownRedis();
}

/**
* @dataProvider redisClientDataProvider
*/
public function testTransactionIsNotOpenedWhenSerializationFails($redisClient): void
{
$this->app['config']['cache.default'] = 'redis';
$this->app['config']['database.redis.client'] = $redisClient;

$cache = $this->app->make('cache.psr6');

$item = $cache->getItem('foo');

$item->set(new Unserializable());
$item->expiresAfter(60);

$cache->save($item);

Cache::store('redis')->get('foo');
}

/**
* @return array
*/
public static function redisClientDataProvider(): array
{
return [
['predis'],
['phpredis'],
];
}
}

0 comments on commit 9698de4

Please sign in to comment.