-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7836 from ProcessMaker/FOUR-21263
FOUR-21263 implement a general method to index cache keys
- Loading branch information
Showing
6 changed files
with
252 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
namespace ProcessMaker\Cache; | ||
|
||
use Exception; | ||
use Illuminate\Support\Facades\Log; | ||
use Illuminate\Support\Facades\Redis; | ||
|
||
abstract class CacheManagerBase | ||
{ | ||
/** | ||
* The available cache connections. | ||
* | ||
* @var array | ||
*/ | ||
protected const AVAILABLE_CONNECTIONS = ['redis', 'cache_settings']; | ||
|
||
/** | ||
* Retrieve an array of cache keys that match a specific pattern. | ||
* | ||
* @param string $pattern The pattern to match. | ||
* @param string|null $connection The cache connection to use. | ||
* | ||
* @return array An array of cache keys that match the pattern. | ||
*/ | ||
public function getKeysByPattern(string $pattern, string $connection = null, string $prefix = null): array | ||
{ | ||
if (!$connection) { | ||
$connection = config('cache.default'); | ||
} | ||
|
||
if (!$prefix) { | ||
$prefix = config('cache.prefix'); | ||
} | ||
|
||
if (!in_array($connection, self::AVAILABLE_CONNECTIONS)) { | ||
throw new CacheManagerException('`getKeysByPattern` method only supports Redis connections.'); | ||
} | ||
|
||
try { | ||
// Get all keys | ||
$keys = Redis::connection($connection)->keys($prefix . '*'); | ||
// Filter keys by pattern | ||
return array_filter($keys, fn ($key) => preg_match('/' . $pattern . '/', $key)); | ||
} catch (Exception $e) { | ||
Log::info('CacheManagerBase: ' . $e->getMessage()); | ||
} | ||
|
||
return []; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace ProcessMaker\Cache; | ||
|
||
use Exception; | ||
|
||
class CacheManagerException extends Exception | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
namespace ProcessMaker\Console\Commands; | ||
|
||
use Illuminate\Console\Command; | ||
|
||
class CacheSettingClear extends Command | ||
{ | ||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'cache:settings-clear'; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Remove all of items from the settings cache'; | ||
|
||
/** | ||
* Execute the console command. | ||
*/ | ||
public function handle() | ||
{ | ||
\SettingCache::clear(); | ||
|
||
$this->info('Settings cache cleared.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?php | ||
|
||
namespace Tests\Feature\Cache; | ||
|
||
use Exception; | ||
use Illuminate\Support\Facades\Log; | ||
use Illuminate\Support\Facades\Redis; | ||
use ProcessMaker\Cache\CacheManagerBase; | ||
use ProcessMaker\Cache\CacheManagerException; | ||
use Tests\TestCase; | ||
|
||
class CacheManagerBaseTest extends TestCase | ||
{ | ||
protected $cacheManagerBase; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
config()->set('cache.default', 'redis'); | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
config()->set('cache.default', 'array'); | ||
|
||
parent::tearDown(); | ||
} | ||
|
||
public function testGetKeysByPatternWithValidConnectionAndMatchingKeys() | ||
{ | ||
$this->cacheManagerBase = $this->getMockForAbstractClass(CacheManagerBase::class); | ||
|
||
$pattern = 'test-pattern'; | ||
$prefix = config('cache.prefix'); | ||
$keys = [$prefix . ':test-pattern:1', $prefix . ':test-pattern:2']; | ||
|
||
Redis::shouldReceive('connection') | ||
->with('redis') | ||
->andReturnSelf(); | ||
|
||
Redis::shouldReceive('keys') | ||
->with($prefix . '*') | ||
->andReturn($keys); | ||
|
||
$result = $this->cacheManagerBase->getKeysByPattern($pattern); | ||
|
||
$this->assertCount(2, $result); | ||
$this->assertEquals($keys, $result); | ||
} | ||
|
||
public function testGetKeysByPatternWithValidConnectionAndNoMatchingKeys() | ||
{ | ||
$this->cacheManagerBase = $this->getMockForAbstractClass(CacheManagerBase::class); | ||
|
||
$pattern = 'non-matching-pattern'; | ||
$prefix = config('cache.prefix'); | ||
$keys = [$prefix . ':test-pattern:1', $prefix . ':test-pattern:2']; | ||
|
||
Redis::shouldReceive('connection') | ||
->with('redis') | ||
->andReturnSelf(); | ||
|
||
Redis::shouldReceive('keys') | ||
->with($prefix . '*') | ||
->andReturn($keys); | ||
|
||
$result = $this->cacheManagerBase->getKeysByPattern($pattern); | ||
|
||
$this->assertCount(0, $result); | ||
} | ||
|
||
public function testGetKeysByPatternWithInvalidConnection() | ||
{ | ||
config()->set('cache.default', 'array'); | ||
|
||
$this->cacheManagerBase = $this->getMockForAbstractClass(CacheManagerBase::class); | ||
|
||
$this->expectException(CacheManagerException::class); | ||
$this->expectExceptionMessage('`getKeysByPattern` method only supports Redis connections.'); | ||
|
||
$this->cacheManagerBase->getKeysByPattern('pattern'); | ||
} | ||
|
||
public function testGetKeysByPatternWithExceptionDuringKeyRetrieval() | ||
{ | ||
$this->cacheManagerBase = $this->getMockForAbstractClass(CacheManagerBase::class); | ||
|
||
$pattern = 'test-pattern'; | ||
$prefix = config('cache.prefix'); | ||
|
||
Redis::shouldReceive('connection') | ||
->with('redis') | ||
->andReturnSelf(); | ||
|
||
Redis::shouldReceive('keys') | ||
->with($prefix . '*') | ||
->andThrow(new Exception('Redis error')); | ||
|
||
Log::shouldReceive('info') | ||
->with('CacheManagerBase: ' . 'Redis error') | ||
->once(); | ||
|
||
$result = $this->cacheManagerBase->getKeysByPattern($pattern); | ||
|
||
$this->assertCount(0, $result); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters