Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
5415967
FOUR-20912: Enhance Test Coverage for Screens Functionality Before A…
rodriquelca Nov 25, 2024
d3dcecc
test: login option settings
devmiguelangel Nov 26, 2024
da55d6c
test: session control settings
devmiguelangel Nov 26, 2024
6b971b3
Add a negative test, when the storage fails. Something
rodriquelca Nov 26, 2024
d2ca132
Merge pull request #7764 from ProcessMaker/feature/FOUR-20912
caleeli Nov 26, 2024
6f48021
test: auth settings
devmiguelangel Nov 26, 2024
a3048b5
Merge pull request #7766 from ProcessMaker/FOUR-20504
caleeli Nov 27, 2024
5ecd24d
feat: add a custom cache class structure
devmiguelangel Nov 29, 2024
e4deb5a
test: add tests for SettingCache methods
devmiguelangel Nov 29, 2024
b2b983d
feat: organize cache classes
devmiguelangel Nov 29, 2024
3cf3c6d
Merge branch 'release-2024-fall' into epic/FOUR-20326
devmiguelangel Nov 29, 2024
0470d27
Merge branch 'epic/FOUR-20326' into FOUR-20467
devmiguelangel Nov 29, 2024
2a1b3b5
fix(cr): enhance settings cache error handling and configuration check
devmiguelangel Nov 29, 2024
e21e9d8
Merge pull request #7779 from ProcessMaker/FOUR-20467
caleeli Nov 29, 2024
d4e09e5
ref: remame setting cache manager test
devmiguelangel Dec 2, 2024
655d803
test: get setting from cache
devmiguelangel Dec 2, 2024
f794927
FOUR-20911: Caching Screens
rodriquelca Dec 2, 2024
1204f7c
feat: get setting from cache
devmiguelangel Dec 3, 2024
c9b9b20
Merge branch 'release-2024-fall' into epic/FOUR-20326
devmiguelangel Dec 3, 2024
349b512
Merge branch 'epic/FOUR-20326' into FOUR-20492
devmiguelangel Dec 3, 2024
6546a4e
feat: enhance setting cache manager
devmiguelangel Dec 3, 2024
291d1f9
fix failing test in TaskControllerTestV1
rodriquelca Dec 3, 2024
10df63b
FOUR-20915: Cache Performance Monitoring
rodriquelca Dec 4, 2024
79b2320
add documentation
rodriquelca Dec 4, 2024
a0fc099
fix CR notes
rodriquelca Dec 4, 2024
571a0c7
Merge remote-tracking branch 'origin/feature/FOUR-20911' into feature…
rodriquelca Dec 4, 2024
de2a645
Merge pull request #7787 from ProcessMaker/feature/FOUR-20911
caleeli Dec 4, 2024
be4afac
implement CacheMetricDcorators to the cacheFactory
rodriquelca Dec 4, 2024
697821d
add documentations
rodriquelca Dec 4, 2024
d628a7c
remove alternatives form documentation
rodriquelca Dec 4, 2024
7cf1abf
remove savedsarch config file
rodriquelca Dec 4, 2024
78102cb
cleand code, scredule metrics comand daily
rodriquelca Dec 4, 2024
955b0ac
remove command tests
rodriquelca Dec 4, 2024
6b860a6
Merge pull request #7783 from ProcessMaker/FOUR-20492
caleeli Dec 4, 2024
272d3b7
Merge branch 'release-2024-fall' into epic/FOUR-20326
devmiguelangel Dec 5, 2024
f3021b1
feat: clear by pattern, clear all settings
devmiguelangel Dec 5, 2024
3370ea6
feat: add cache settings to .env.example
devmiguelangel Dec 5, 2024
33c010d
FOUR-20913: invalidate Screen Cache on Translation changes
rodriquelca Dec 5, 2024
2c61caa
fix(cr): enhance SettingCacheManager to determine cache driver and im…
devmiguelangel Dec 5, 2024
207370a
FOUR-20913: Invalidate Screen Cache on Translation changes
rodriquelca Dec 6, 2024
20fa736
clear debug
rodriquelca Dec 6, 2024
e1e6b4e
Merge pull request #7795 from ProcessMaker/FOUR-20532
caleeli Dec 6, 2024
8ba8562
fi bad event service provider definition
rodriquelca Dec 6, 2024
5d76ff0
fix test cache factory
rodriquelca Dec 6, 2024
aae1743
Merge pull request #7793 from ProcessMaker/feature/FOUR-20915
caleeli Dec 6, 2024
127846d
FOUR-20913: invalidate Screen Cache on Translation changes
rodriquelca Dec 5, 2024
d0fa80b
FOUR-20913: Invalidate Screen Cache on Translation changes
rodriquelca Dec 6, 2024
cf9db1b
clear debug
rodriquelca Dec 6, 2024
1515237
fi bad event service provider definition
rodriquelca Dec 6, 2024
b78499d
fix test cache factory
rodriquelca Dec 6, 2024
5e9f39c
update ScreenCacheManagerTest for failing tests
rodriquelca Dec 6, 2024
039ea48
fix merge conflicts
rodriquelca Dec 6, 2024
aa36aab
complete getOrCache method
rodriquelca Dec 6, 2024
9a7be50
feat: invalidate settings cache
devmiguelangel Dec 6, 2024
9c9ccc0
Merge pull request #7803 from ProcessMaker/feature/FOUR-20913
caleeli Dec 6, 2024
5665379
Merge pull request #7808 from ProcessMaker/FOUR-20909
caleeli Dec 6, 2024
98a9492
add misses and Miss Ratio
rodriquelca Dec 12, 2024
fa63a6a
Merge branch 'release-2024-fall' into epic/FOUR-20326
devmiguelangel Dec 17, 2024
6612e70
feat: add the getKeysByPattern method
devmiguelangel Dec 17, 2024
af794c9
feat: enhance SettingCacheManager to extend CacheABC and improve cach…
devmiguelangel Dec 17, 2024
aec1487
feat: add console command to clear settings cache
devmiguelangel Dec 17, 2024
88e6e76
refactor: rename CacheABC to CacheManagerBase
devmiguelangel Dec 17, 2024
df09a43
fix(cr): introduce CacheManagerException and update error handling in…
devmiguelangel Dec 17, 2024
379c687
fix: improve cache driver handling
devmiguelangel Dec 18, 2024
48f0e56
refactor: update SettingCacheManager
devmiguelangel Dec 18, 2024
24075d9
FOUR-20917: Ensure Scalable Caching Solution
rodriquelca Dec 18, 2024
0218c1c
refactor: simplify cache driver handling
devmiguelangel Dec 18, 2024
9856bf6
standardize invalidate cache
rodriquelca Dec 18, 2024
5f4c607
feat: enhance getKeysByPattern method to accept a connection
devmiguelangel Dec 18, 2024
faf2411
improve clearCompiledAssets for the cache manager
rodriquelca Dec 19, 2024
2e96f68
complete Setting cache factory
rodriquelca Dec 19, 2024
77994af
fix: update SettingCacheTest to use Cache facade for consistency
devmiguelangel Dec 19, 2024
965fcf1
fix TaskControllerTest
rodriquelca Dec 19, 2024
626adf1
fix: clean code
devmiguelangel Dec 19, 2024
d060119
fix failing test removing mockery
rodriquelca Dec 19, 2024
fafc69e
Merge pull request #7836 from ProcessMaker/FOUR-21263
caleeli Dec 19, 2024
5077d24
fix merge conflicts
rodriquelca Dec 19, 2024
c1ddde2
Remove logging in Setting model
caleeli Dec 19, 2024
58433ea
Merge pull request #7841 from ProcessMaker/feature/FOUR-20917
caleeli Dec 19, 2024
908abff
Cache screen fields
caleeli Jan 2, 2025
4407335
Add unit tests for loading screen fields from cache
caleeli Jan 2, 2025
9008be1
Implement cache handling for screen fields by checking for empty coll…
caleeli Jan 3, 2025
d061116
Merge pull request #7858 from ProcessMaker/FOUR-21383
caleeli Jan 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions ProcessMaker/Cache/CacheManagerBase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?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 [];
}
}
9 changes: 9 additions & 0 deletions ProcessMaker/Cache/CacheManagerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace ProcessMaker\Cache;

use Exception;

class CacheManagerException extends Exception
{
}
56 changes: 29 additions & 27 deletions ProcessMaker/Cache/Settings/SettingCacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,42 @@
namespace ProcessMaker\Cache\Settings;

use Illuminate\Cache\CacheManager;
use Illuminate\Cache\Repository;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use ProcessMaker\Cache\CacheInterface;
use ProcessMaker\Cache\CacheManagerBase;

class SettingCacheManager implements CacheInterface
class SettingCacheManager extends CacheManagerBase implements CacheInterface
{
const DEFAULT_CACHE_DRIVER = 'cache_settings';

protected CacheManager $cacheManager;
protected CacheManager $manager;

protected Repository $cacheManager;

public function __construct(CacheManager $cacheManager)
{
$driver = $this->determineCacheDriver();
$this->manager = $cacheManager;
$this->setCacheDriver();
}

/**
* Determine and set the cache driver to use.
*
* @param CacheManager $cacheManager
*
* @return void
*/
private function setCacheDriver(): void
{
$defaultCache = config('cache.default');
$isAvailableConnection = in_array($defaultCache, self::AVAILABLE_CONNECTIONS);

$this->cacheManager = $cacheManager;
$this->cacheManager->store($driver);
// Set the cache driver to use
$cacheDriver = $isAvailableConnection ? self::DEFAULT_CACHE_DRIVER : $defaultCache;
// Store the cache driver
$this->cacheManager = $this->manager->store($cacheDriver);
}

/**
Expand All @@ -44,21 +64,6 @@ public function createKey(array $params): string
);
}

/**
* Determine the cache driver to use.
*
* @return string
*/
private function determineCacheDriver(): string
{
$defaultCache = config('cache.default');
if (in_array($defaultCache, ['redis', 'cache_settings'])) {
return self::DEFAULT_CACHE_DRIVER;
}

return $defaultCache;
}

/**
* Dynamically pass method calls to the cache manager.
*
Expand Down Expand Up @@ -163,22 +168,19 @@ public function clear(): bool
*/
public function clearBy(string $pattern): void
{
$defaultDriver = $this->cacheManager->getDefaultDriver();
$defaultDriver = $this->manager->getDefaultDriver();

if ($defaultDriver !== 'cache_settings') {
throw new SettingCacheException('The cache driver must be Redis.');
}

try {
// get the connection name from the cache manager
$connection = $this->cacheManager->connection()->getName();
// Get all keys
$keys = Redis::connection($connection)->keys($this->cacheManager->getPrefix() . '*');
$prefix = $this->manager->getPrefix();
// Filter keys by pattern
$matchedKeys = array_filter($keys, fn ($key) => preg_match('/' . $pattern . '/', $key));
$matchedKeys = $this->getKeysByPattern($pattern, $defaultDriver, $prefix);

if (!empty($matchedKeys)) {
Redis::connection($connection)->del($matchedKeys);
Redis::connection($defaultDriver)->del($matchedKeys);
}
} catch (\Exception $e) {
Log::error('SettingCacheException' . $e->getMessage());
Expand Down
32 changes: 32 additions & 0 deletions ProcessMaker/Console/Commands/CacheSettingClear.php
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.');
}
}
4 changes: 3 additions & 1 deletion ProcessMaker/Console/Commands/RevokeOauthAccessTokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace ProcessMaker\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class RevokeOauthAccessTokens extends Command
{
Expand Down Expand Up @@ -37,11 +37,13 @@ public function handle()

if (!$name && !$after && !$clientId) {
$this->error('At least one of --name, --after, or --client_id must be specified.');

return;
}

if (!$noInteraction && !$this->confirm('Are you sure you want to revoke this certificate?')) {
$this->info('Certificate revocation cancelled.');

return;
}

Expand Down
108 changes: 108 additions & 0 deletions tests/Feature/Cache/CacheManagerBaseTest.php
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);
}
}
Loading