Skip to content

Commit 7418fc7

Browse files
committed
fix methods with connection
1 parent f50abe5 commit 7418fc7

9 files changed

+262
-62
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,3 +468,4 @@ resources/frontend/default/js/components/clientComponents/*
468468

469469
#escludo la cartella personal_scripts presente in utility così ognuno può avere i suoi script personali
470470
utility/personal_scripts
471+
/storage/logs/tests/.phpunit.cache/test-results

composer.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@
2020
}
2121
],
2222
"require": {
23-
"php" : "^8.0",
24-
"illuminate/support": "^9.0|^10.0|^11.0" ,
23+
"php": "^8.0",
24+
"ext-redis": "*",
25+
"illuminate/support": "^9.0|^10.0|^11.0",
2526
"laravel/framework": "^9.0|^10.0|^11.0",
26-
"predis/predis": "^2.0",
27-
"ext-redis": "*"
27+
"predis/predis": "^2.0"
2828
},
2929
"require-dev": {
30+
"m6web/redis-mock": "^5.6",
3031
"phpunit/phpunit": "^9.5|^10.0|^11.0",
3132
"orchestra/testbench": "^7.0|^8.0|^9.0",
3233
"mockery/mockery": "^1.5",

composer.lock

Lines changed: 52 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Console/ProcessCacheInvalidationEventsCommand.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,16 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t
114114

115115
// Prepare list of all identifiers to fetch last invalidation times
116116
$allIdentifiers = [];
117-
118117
foreach ($eventsByIdentifier as $key => $eventsGroup) {
119118
$allIdentifiers[] = $key;
120119
foreach ($eventsGroup as $event) {
121-
$eventAssociations = $associations->get($event->id, collect());
120+
$eventAssociations = $associations->where('event_id', '=', $event->id);
122121
foreach ($eventAssociations as $assoc) {
123122
$assocKey = $assoc->associated_type . ':' . $assoc->associated_identifier;
124123
$allIdentifiers[] = $assocKey;
125124
}
126125
}
127126
}
128-
129127
// Fetch last invalidation times in bulk
130128
$lastInvalidationTimes = $this->getLastInvalidationTimes(array_unique($allIdentifiers));
131129

@@ -136,7 +134,7 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t
136134
// Get associated identifiers for the events
137135
$associatedIdentifiers = [];
138136
foreach ($eventsGroup as $event) {
139-
$eventAssociations = $associations->get($event->id, collect());
137+
$eventAssociations = $associations->where('event_id', '=', $event->id);
140138
foreach ($eventAssociations as $assoc) {
141139
$assocKey = $assoc->associated_type . ':' . $assoc->associated_identifier;
142140
$associatedIdentifiers[$assocKey] = [
@@ -150,7 +148,6 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t
150148
// Build a list of all identifiers to check
151149
$identifiersToCheck = [$key];
152150
$identifiersToCheck = array_merge($identifiersToCheck, array_keys($associatedIdentifiers));
153-
154151
$lastInvalidationTimesSubset = array_intersect_key($lastInvalidationTimes, array_flip($identifiersToCheck));
155152

156153
$shouldInvalidate = $this->shouldInvalidateMultiple($identifiersToCheck, $lastInvalidationTimesSubset, $invalidationWindow);
@@ -314,13 +311,15 @@ protected function updateLastInvalidationTimes(array $identifiers): void
314311
*/
315312
protected function processBatch(array $batchIdentifiers, array $eventsToUpdate): void
316313
{
314+
317315
// Begin transaction for the batch
318316
DB::beginTransaction();
319317

320318
try {
321319
// Separate keys and tags
322320
$keys = [];
323321
$tags = [];
322+
324323
foreach ($batchIdentifiers as $item) {
325324
switch ($item['type']) {
326325
case 'key':
@@ -386,6 +385,7 @@ protected function invalidateKeys(array $keys): void
386385
{
387386
$callback = config('super_cache_invalidate.key_invalidation_callback');
388387

388+
389389
// Anche in questo caso va fatto un loop perchè le chiavi potrebbero stare in database diversi
390390
foreach ($keys as $keyAndConnectionName) {
391391
[$key, $connection_name] = explode('§', $keyAndConnectionName);
@@ -398,6 +398,7 @@ protected function invalidateKeys(array $keys): void
398398

399399
// oppure di default uso Laravel
400400
$storeName = $this->getStoreFromConnectionName($connection_name);
401+
401402
if ($storeName === null) {
402403
return;
403404
}

src/Console/PruneCacheInvalidationDataCommand.php

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ class PruneCacheInvalidationDataCommand extends Command
2828
* @param string $tableName The name of the table
2929
* @param int $retentionPartitionKey The partition key cutoff
3030
*/
31-
protected function pruneTable(string $tableName, int $retentionPartitionKey): void
31+
protected function pruneTable(string $tableName, int $retentionPartitionKey, ?int $minPartitionValueToExclude = 0): void
3232
{
3333
// Fetch partition names
34-
$partitions = $this->getPartitionsFromDb($tableName, $retentionPartitionKey);
34+
$partitions = $this->getPartitionsFromDb($tableName, $retentionPartitionKey, $minPartitionValueToExclude);
3535

3636
if (empty($partitions)) {
3737
$this->info("No partitions to prune for table {$tableName}.");
@@ -55,37 +55,47 @@ public function handle(): void
5555
{
5656
$months = (int) $this->option('months');
5757
$retentionDate = now()->subMonths($months);
58-
$retentionPartitionKey = $retentionDate->year * 100 + $retentionDate->week();
5958

6059
// Prune tables
61-
$tables = [
62-
'cache_invalidation_events',
63-
'cache_invalidation_timestamps',
64-
'cache_invalidation_event_associations',
65-
];
60+
$this->pruneTable('cache_invalidation_timestamps', ($retentionDate->year * 100 + $retentionDate->week) + 1);
61+
$this->pruneTable('cache_invalidation_event_associations', ($retentionDate->year * 100 + $retentionDate->week) + 1);
6662

67-
foreach ($tables as $tableName) {
68-
$this->pruneTable($tableName, $retentionPartitionKey);
63+
$shards = config('super_cache_invalidate.total_shards', 10);
64+
$priorities = [0, 1];
65+
66+
$minPartitionValueToExclude = 0;
67+
foreach ($priorities as $priority) {
68+
for ($shard = 0; $shard < $shards; $shard++) {
69+
$minPartitionValueToExclude = ($priority * $shards) + $shard + 1;
70+
}
71+
}
72+
$arrPartitionValues = [];
73+
foreach ($priorities as $priority) {
74+
for ($shard = 0; $shard < $shards; $shard++) {
75+
$arrPartitionValues[] = (($retentionDate->year * 10000) + ($retentionDate->week * 100) + ($priority * $shards) + $shard) + 1;
76+
}
6977
}
78+
$maxPartitionValueToInclude = max($arrPartitionValues);
79+
$this->pruneTable('cache_invalidation_events', $maxPartitionValueToInclude, $minPartitionValueToExclude);
7080

7181
$this->info('Old cache invalidation data has been pruned.');
7282
}
7383

7484
/**
7585
* @param string $tableName
76-
* @param int $retentionPartitionKey
86+
* @param int $maxPartitionValueToInclude
7787
* @return array
7888
*/
79-
protected function getPartitionsFromDb(string $tableName, int $retentionPartitionKey): array
89+
protected function getPartitionsFromDb(string $tableName, int $maxPartitionValueToInclude, $minPartitionValueToExclude): array
8090
{
8191
$partitions = DB::select('
8292
SELECT PARTITION_NAME, PARTITION_DESCRIPTION
8393
FROM INFORMATION_SCHEMA.PARTITIONS
8494
WHERE TABLE_SCHEMA = DATABASE()
8595
AND TABLE_NAME = ?
8696
AND PARTITION_NAME IS NOT NULL
87-
AND PARTITION_DESCRIPTION < ?
88-
', [$tableName, $retentionPartitionKey]);
97+
AND PARTITION_DESCRIPTION < ? AND PARTITION_DESCRIPTION > ?
98+
', [$tableName, $maxPartitionValueToInclude, $minPartitionValueToExclude]);
8999
return $partitions;
90100
}
91101
}

tests/Unit/ProcessCacheInvalidationEventsTest.php

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,20 @@
22

33
namespace Padosoft\SuperCacheInvalidate\Test\Unit;
44

5-
use PHPUnit\Framework\TestCase;
65
use Illuminate\Support\Facades\DB;
76
use Illuminate\Support\Facades\Cache;
8-
use Padosoft\SuperCacheInvalidate\Console\ProcessCacheInvalidationEventsCommand;
9-
use Padosoft\SuperCacheInvalidate\Helpers\SuperCacheInvalidationHelper;
107
use Carbon\Carbon;
8+
use Mockery;
9+
use Padosoft\SuperCacheInvalidate\Helpers\SuperCacheInvalidationHelper;
1110

1211
class ProcessCacheInvalidationEventsTest extends TestCase
1312
{
14-
protected ProcessCacheInvalidationEventsCommand $command;
13+
protected SuperCacheInvalidationHelper $helper;
1514

1615
protected function setUp(): void
1716
{
1817
parent::setUp();
19-
$helper = new SuperCacheInvalidationHelper();
20-
$this->command = new ProcessCacheInvalidationEventsCommand($helper);
18+
$this->helper = new SuperCacheInvalidationHelper();
2119
}
2220

2321
public function testProcessEventsWithAssociatedIdentifiersWithinWindow(): void
@@ -26,9 +24,12 @@ public function testProcessEventsWithAssociatedIdentifiersWithinWindow(): void
2624
$events = collect([
2725
(object)[
2826
'id' => 1,
29-
'type' => 'tag',
27+
'type' => 'key',
3028
'identifier' => 'article_ID:7',
31-
'event_time' => Carbon::now()->subSeconds(10),
29+
'reason' => 'Article 7 removed',
30+
'connection_name' => 'default',
31+
'shard' => 1,
32+
'priority' => 1
3233
],
3334
]);
3435

@@ -37,44 +38,90 @@ public function testProcessEventsWithAssociatedIdentifiersWithinWindow(): void
3738
'event_id' => 1,
3839
'associated_type' => 'tag',
3940
'associated_identifier' => 'plp:sport',
41+
'connection_name' => 'default',
4042
],
4143
]);
4244

4345
// Mock DB queries
44-
DB::shouldReceive('table->where->where->where->where->orderBy->limit->get')
46+
DB::shouldReceive('table->where->where->where->where->where->orderBy->limit->get')
4547
->andReturn($events)
4648
;
4749

48-
DB::shouldReceive('table->whereIn->get')
50+
DB::shouldReceive('table->whereIn->get->groupBy')
4951
->andReturn($associations)
5052
;
5153

5254
// Mock last invalidation times
53-
DB::shouldReceive('select')->andReturn([
55+
DB::shouldReceive('select')
56+
->andReturn([
5457
(object)[
55-
'identifier_type' => 'tag',
58+
'identifier_type' => 'key',
5659
'identifier' => 'article_ID:7',
57-
'last_invalidated' => Carbon::now()->subSeconds(40)->toDateTimeString(),
60+
'last_invalidated' => Carbon::now()->subSeconds(120)->toDateTimeString(),
5861
],
5962
(object)[
6063
'identifier_type' => 'tag',
6164
'identifier' => 'plp:sport',
62-
'last_invalidated' => Carbon::now()->subSeconds(20)->toDateTimeString(),
65+
'last_invalidated' => Carbon::now()->subSeconds(180)->toDateTimeString(),
6366
],
6467
]);
6568

69+
// Mock update or insert
70+
DB::shouldReceive('table->updateOrInsert')->twice(); //1 per la chiave e 1 per il tag
71+
72+
DB::shouldReceive('beginTransaction')->once();
73+
74+
// CHIAVE
6675
// Mock Cache
67-
Cache::shouldReceive('tags->flush')->never();
76+
Cache::shouldReceive('store')
77+
->with('redis-store-1') // Nome dello store
78+
->once()
79+
->andReturn(Mockery::mock(\Illuminate\Contracts\Cache\Repository::class, function ($mock) {
80+
// Mockiamo il comportamento del repository cache
81+
$mock->shouldReceive('forget')
82+
->withArgs(function ($key) {
83+
// controllo che la chiave sia proprio quella
84+
$this->assertEquals('article_ID:7', $key);
85+
return true; // Indica che l'argomento è accettabile
86+
})
87+
->once()
88+
->andReturn(true);
89+
}));
6890

69-
// Mock update or insert
70-
DB::shouldReceive('table->updateOrInsert')->never();
91+
// TAG
92+
// Mock Cache
93+
Cache::shouldReceive('store')
94+
->with('redis-store-1') // Nome dello store
95+
->once()
96+
->andReturn(Mockery::mock(\Illuminate\Contracts\Cache\Repository::class, function ($mock) {
97+
// Mockiamo il comportamento del repository cache
98+
$mock->shouldReceive('tags')
99+
->withArgs(function ($tags) {
100+
// controllo che la chiave sia proprio quella
101+
$this->assertEquals(['plp:sport'], $tags);
102+
return true; // Indica che l'argomento è accettabile
103+
})
104+
->once()
105+
->andReturn(Mockery::mock(\Illuminate\Cache\TaggedCache::class, function ($taggedCacheMock) {
106+
$taggedCacheMock->shouldReceive('flush')
107+
->once()
108+
->andReturn(true);
109+
}));
110+
}));
71111

72112
// Mock event update
73113
DB::shouldReceive('table->whereIn->update')->once();
74114

75-
// Run the command
76-
$this->command->handle();
115+
DB::shouldReceive('commit')->once();
77116

78-
// Assertions are handled by Mockery expectations
117+
// Run the command
118+
// Run the command
119+
$this->artisan('supercache:process-invalidation', [
120+
'--shard' => 0,
121+
'--priority' => 0,
122+
'--limit' => 1,
123+
'--tag-batch-size' => 1,
124+
'--connection_name' => 'default',
125+
]);
79126
}
80127
}

0 commit comments

Comments
 (0)