Skip to content

Commit 1d877b3

Browse files
committed
gestione event_time
1 parent 1520a0a commit 1d877b3

File tree

4 files changed

+67
-106
lines changed

4 files changed

+67
-106
lines changed

database/migrations/2024_11_20_200800_create_cache_invalidation_events_table.php renamed to database/migrations/2025_01_08_400999_create_cache_invalidation_events_table.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212
protected function generatePartitionSQL(): string
1313
{
14-
$startYear = 2024;
14+
$startYear = 2025;
1515
$endYear = 2030;
1616
$shards = config('super_cache_invalidate.total_shards', 10);
1717
$priorities = [0, 1]; // Adjust as needed
@@ -21,9 +21,11 @@ protected function generatePartitionSQL(): string
2121
// Partitions for unprocessed events
2222
foreach ($priorities as $priority) {
2323
for ($shard = 0; $shard < $shards; $shard++) {
24-
$partitionName = "p_unprocessed_s{$shard}_p{$priority}";
25-
$partitionValue = ($priority * $shards) + $shard + 1;
26-
$partitionStatements[] = "PARTITION {$partitionName} VALUES LESS THAN ({$partitionValue})";
24+
$partitionValue = ($priority * 10) + $shard;
25+
//$partitionName = "p_unprocessed_s{$shard}_p{$priority}";
26+
$partitionName = "p_unprocessed_{$partitionValue}";
27+
$nextPartitionKey = $partitionValue + 1;
28+
$partitionStatements[] = "PARTITION {$partitionName} VALUES LESS THAN ({$nextPartitionKey})";
2729
}
2830
}
2931

@@ -32,9 +34,11 @@ protected function generatePartitionSQL(): string
3234
for ($week = 1; $week <= 53; $week++) {
3335
foreach ($priorities as $priority) {
3436
for ($shard = 0; $shard < $shards; $shard++) {
35-
$partitionKey = ($year * 10000) + ($week * 100) + ($priority * $shards) + $shard;
36-
$nextPartitionKey = $partitionKey + 1;
37-
$partitionName = "p_s{$shard}_p{$priority}_{$year}w{$week}";
37+
$partitionValue = ($year * 10000) + ($week * 100) + ($priority * 10) + $shard;
38+
//$nextPartitionKey = $partitionKey + 1;
39+
//$partitionName = "p_s{$shard}_p{$priority}_{$year}w{$week}";
40+
$partitionName = "p_processed_{$partitionValue}";
41+
$nextPartitionKey = $partitionValue + 1;
3842
$partitionStatements[] = "PARTITION {$partitionName} VALUES LESS THAN ({$nextPartitionKey})";
3943
}
4044
}
@@ -53,9 +57,9 @@ protected function generatePartitionSQL(): string
5357
*/
5458
public function up(): void
5559
{
56-
if (Schema::hasTable('cache_invalidation_events')) {
57-
return;
58-
}
60+
61+
// Per i siti in cui l'ho già creata (lvr, Santha, Pissei) la ricreo con le partizioni giuste
62+
Schema::dropIfExists('cache_invalidation_events');
5963

6064
Schema::create('cache_invalidation_events', function (Blueprint $table) {
6165
//$table->bigIncrements('id');
@@ -66,16 +70,18 @@ public function up(): void
6670
$table->string('reason')->nullable()->comment('Reason for the invalidation (for logging purposes)');
6771
$table->tinyInteger('priority')->default(0)->comment('Priority of the event');
6872
$table->dateTime('event_time')->default(DB::raw('CURRENT_TIMESTAMP'))->comment('Timestamp when the event was created');
73+
$table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->comment('Timestamp when the record was created');
74+
$table->dateTime('updated_at')->default(DB::raw('CURRENT_TIMESTAMP'))->comment('Timestamp when the record was updated');
6975
$table->boolean('processed')->default(0)->comment('Flag indicating whether the event has been processed');
7076
$table->integer('shard')->comment('Shard number for parallel processing');
7177

7278
// Partition key as a generated stored column
7379
$table->integer('partition_key')->storedAs('
7480
CASE
7581
WHEN `processed` = 0 THEN
76-
(`priority` * `shard`) + `shard` + 1
82+
(`priority` * 10) + `shard`
7783
ELSE
78-
(YEAR(`event_time`) * 10000) + (WEEK(`event_time`, 3) * 100) + (`priority` * `shard`) + `shard`
84+
(YEAR(`event_time`) * 10000) + (WEEK(`event_time`, 3) * 100) + (`priority` * 10) + `shard`
7985
END
8086
')->comment('Partition key for efficient querying and partitioning');
8187

src/Console/ProcessCacheInvalidationEventsCommand.php

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ private function getStoreFromConnectionName(string $connection_name): ?string
6464
/**
6565
* Process cache invalidation events.
6666
*
67-
* @param int $shardId The shard number to process
68-
* @param int $priority The priority level
69-
* @param int $limit Maximum number of events to fetch per batch
67+
* @param int $shardId The shard number to process
68+
* @param int $priority The priority level
69+
* @param int $limit Maximum number of events to fetch per batch
7070
* @param int $tagBatchSize Number of identifiers to process per batch
7171
*
7272
* @throws \Exception
@@ -78,10 +78,8 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t
7878
$invalidationWindow = config('super_cache_invalidate.invalidation_window');
7979

8080
// Fetch a batch of unprocessed events
81-
$partitionCache_invalidation_events = $this->helper->getCacheInvalidationEventsPartitionName($shardId, $priority);
82-
81+
$partitionCache_invalidation_events = $this->helper->getCacheInvalidationEventsUnprocessedPartitionName($shardId, $priority);
8382
$events = DB::table(DB::raw("`cache_invalidation_events` PARTITION ({$partitionCache_invalidation_events})"))
84-
//->from(DB::raw("`{$this->from}` PARTITION ({$partitionsString})"))
8583
->where('processed', '=', 0)
8684
->where('shard', '=', $shardId)
8785
->where('priority', '=', $priority)
@@ -93,7 +91,6 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t
9391
->get()
9492
;
9593

96-
//ds($partitionCache_invalidation_events . ' -> Shard (' . $shardId . ') Priority (' . $priority . ') Record = ' . $events->count());
9794
if ($events->isEmpty()) {
9895
// No more events to process
9996
return;
@@ -309,7 +306,7 @@ protected function updateLastInvalidationTimes(array $identifiers): void
309306

310307
DB::table('cache_invalidation_timestamps')
311308
//DB::table(DB::raw("`cache_invalidation_timestamps` PARTITION ({$partitionCache_invalidation_timestamps})"))
312-
->updateOrInsert(
309+
->updateOrInsert(
313310
['identifier_type' => $type, 'identifier' => $identifier],
314311
['last_invalidated' => $now]
315312
)
@@ -377,8 +374,6 @@ protected function processBatch(array $batchIdentifiers, array $eventsToUpdate,
377374
}
378375

379376
$shards = config('super_cache_invalidate.total_shards', 10);
380-
//$partitionCache_invalidation_events = $this->helper->getCacheInvalidationEventsPartitionName($shard, $priority);
381-
382377
while ($attempts < $maxAttempts && !$updatedOk) {
383378
//$partitionCache_invalidation_events_processed = $this->helper->getCacheInvalidationEventsProcessedPartitionName($shard, $priority, $eventToUpdate['event_time']);
384379

@@ -390,11 +385,11 @@ protected function processBatch(array $batchIdentifiers, array $eventsToUpdate,
390385
DB::statement('SET UNIQUE_CHECKS=0;');
391386

392387
// Mark event as processed
393-
//DB::table(DB::raw("`cache_invalidation_events` PARTITION ({$partitionCache_invalidation_events}, {$partitionCache_invalidation_events_processed})"))
394-
DB::table("cache_invalidation_events")
395-
->whereIn('id', array_column($eventsToUpdate, 'id'))
396-
->whereIn('partition_key', array_column($eventsToUpdate, 'partition_key'))
397-
->update(['processed' => 1])
388+
// QUI NON VA USATA PARTITION perchè la cross partition è più lenta!!!
389+
DB::table('cache_invalidation_events')
390+
->whereIn('id', array_column($eventsToUpdate, 'id'))
391+
->whereIn('partition_key', array_column($eventsToUpdate, 'partition_key'))
392+
->update(['processed' => 1, 'updated_at' => now()])
398393
;
399394
// Riattiva i controlli
400395
DB::statement('SET UNIQUE_CHECKS=1;');

src/Helpers/SuperCacheInvalidationHelper.php

Lines changed: 30 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ class SuperCacheInvalidationHelper
1212
/**
1313
* Insert a cache invalidation event into the database.
1414
*
15-
* @param string $type 'key' or 'tag'
16-
* @param string $identifier The cache key or tag to invalidate
17-
* @param string|null $connection_name The Redis Connection name (optional, 'default')
18-
* @param string|null $reason Reason for invalidation (optional)
19-
* @param int|null $totalShards Total number of shards (from config if null)
20-
* @param int|null $priority Priority of the event
21-
* @param array|null $associatedIdentifiers Optional array of associated tags or keys
15+
* @param string $type 'key' or 'tag'
16+
* @param string $identifier The cache key or tag to invalidate
17+
* @param string|null $connection_name The Redis Connection name (optional, 'default')
18+
* @param string|null $reason Reason for invalidation (optional)
19+
* @param int|null $totalShards Total number of shards (from config if null)
20+
* @param int|null $priority Priority of the event
21+
* @param int|null $processed Processed = 0 o 1
22+
* @param Carbon|null $event_time Orario vero in cui si è richiesta l'invalidazione
2223
*/
2324
public function insertInvalidationEvent(
2425
string $type,
@@ -27,19 +28,20 @@ public function insertInvalidationEvent(
2728
?string $reason = null,
2829
?int $totalShards = 0,
2930
?int $priority = 0,
30-
?array $associatedIdentifiers = [],
31+
?int $processed = 0,
32+
?Carbon $event_time = null,
33+
/*?array $associatedIdentifiers = [],*/
3134
): void {
3235
$shard = crc32($identifier) % ($totalShards > 0 ? $totalShards : config('super_cache_invalidate.total_shards', 10));
33-
3436
$redisConnectionName = $connection_name ?? config('super_cache_invalidate.default_connection_name');
3537
$data = [
3638
'type' => $type,
3739
'identifier' => $identifier,
3840
'connection_name' => $redisConnectionName,
3941
'reason' => $reason,
4042
'priority' => $priority,
41-
'event_time' => now(),
42-
'processed' => 0,
43+
'event_time' => $event_time ?? now(),
44+
'processed' => $processed, // ATTENZIONE, poichè abbiamo solo 2 priorità, nel caso di priorità 1 verrà passato 1 perchè l'invalidazione la fa il progetto
4345
'shard' => $shard,
4446
];
4547

@@ -52,8 +54,17 @@ public function insertInvalidationEvent(
5254

5355
try {
5456
// Cerca di bloccare il record per l'inserimento
55-
$partitionCache_invalidation_events = $this->getCacheInvalidationEventsPartitionName($shard, $priority);
56-
57+
switch ($processed) {
58+
case 0:
59+
$partitionCache_invalidation_events = $this->getCacheInvalidationEventsUnprocessedPartitionName($shard, $priority);
60+
break;
61+
case 1:
62+
$partitionCache_invalidation_events = $this->getCacheInvalidationEventsProcessedPartitionName($shard, $priority, $event_time ?? now());
63+
break;
64+
default:
65+
$attempts = 5; // Mi fermo
66+
throw new \RuntimeException('Invalid value for processed');
67+
}
5768
//$eventId = DB::table(DB::raw("`cache_invalidation_events` PARTITION ({$partitionCache_invalidation_events})"))->insertGetId($data);
5869
DB::table(DB::raw("`cache_invalidation_events` PARTITION ({$partitionCache_invalidation_events})"))->insert($data);
5970
// Insert associated identifiers
@@ -132,71 +143,15 @@ public function releaseShardLock(int $shardId, int $priority, string $lockValue,
132143
}
133144
}
134145

135-
public function getCacheInvalidationEventsPartitionName(int $shardId, int $priorityId): string
136-
{
137-
// Calcola il valore della partizione
138-
$shards = config('super_cache_invalidate.total_shards', 10);
139-
$priorities = [0, 1];
140-
141-
$partitionValueId = ($priorityId * $shards) + $shardId + 1;
142-
143-
// Partitions for unprocessed events
144-
foreach ($priorities as $priority) {
145-
for ($shard = 0; $shard < $shards; $shard++) {
146-
$partitionName = "p_unprocessed_s{$shard}_p{$priority}";
147-
$partitionValue = ($priority * $shards) + $shard + 1;
148-
if ($partitionValueId < $partitionValue) {
149-
return $partitionName;
150-
}
151-
}
152-
}
153-
154-
return '';
155-
}
156-
157-
public function getCacheInvalidationTimestampsPartitionName(Carbon $event_time): string
146+
public function getCacheInvalidationEventsUnprocessedPartitionName(int $shardId, int $priorityId): string
158147
{
159-
$now = now();
160-
$partitionValueId = ($now->year * 100 + $now->weekOfYear) + 1;
161-
$startYear = 2024;
162-
$endYear = 2030;
163-
164-
for ($year = $startYear; $year <= $endYear; $year++) {
165-
for ($week = 1; $week <= 53; $week++) {
166-
$partitionName = "p_{$year}w{$week}";
167-
$partitionValue = ($year * 100 + $week) + 1;
168-
if ($partitionValueId < $partitionValue) {
169-
return $partitionName;
170-
}
171-
}
172-
}
173-
174-
return '';
148+
$partitionValue = ($priorityId * 10) + $shardId;
149+
return "p_unprocessed_{$partitionValue}";
175150
}
176151

177-
public function getCacheInvalidationEventsProcessedPartitionName(int $shardId, int $priorityId, string $event_time): string
152+
public function getCacheInvalidationEventsProcessedPartitionName(int $shardId, int $priorityId, Carbon $event_time): string
178153
{
179-
// Calcola il valore della partizione
180-
$shards = config('super_cache_invalidate.total_shards', 10);
181-
$priorities = [0, 1];
182-
$eventTime = Carbon::parse($event_time);
183-
$partitionValueId = ($eventTime->year * 10000) + ($eventTime->weekOfYear * 100) + ($priorityId * $shards) + $shardId;
184-
// Partitions for processed events
185-
for ($year = $eventTime->year; $year <= ($eventTime->year + 1); $year++) {
186-
for ($week = $eventTime->weekOfYear; $week <= $eventTime->weekOfYear + 1; $week++) {
187-
foreach ($priorities as $priority) {
188-
for ($shard = 0; $shard < $shards; $shard++) {
189-
$partitionKey = ($year * 10000) + ($week * 100) + ($priority * $shards) + $shard;
190-
$partitionValue = $partitionKey + 1;
191-
$partitionName = "p_s{$shard}_p{$priority}_{$year}w{$week}";
192-
if ($partitionValueId < $partitionValue) {
193-
return $partitionName;
194-
}
195-
}
196-
}
197-
}
198-
}
199-
200-
return '';
154+
$partitionValue = ($event_time->year * 10000) + ($event_time->weekOfYear * 100) + ($priorityId * 10) + $shardId;
155+
return "p_processed_{$partitionValue}";
201156
}
202157
}

tests/Unit/SuperCacheInvalidationHelperTest.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,21 @@ protected function setUp(): void
1818
public function testInsertInvalidationEvent(): void
1919
{
2020
// Mock DB insert
21-
DB::shouldReceive('table->insertGetId')->once()->andReturn(1);
22-
21+
DB::shouldReceive('table->insert')->once();
2322
$this->helper->insertInvalidationEvent(
2423
'key',
25-
'test_tag',
24+
'zazzi',
2625
'default',
2726
'Article 7 removed',
2827
1,
29-
1);
28+
0,
29+
1,
30+
now()
31+
);
3032
}
3133

34+
// TODO: da riattivare quando si implemntano per bene le associazioni
35+
/*
3236
public function testInsertInvalidationEventWithAssociations(): void
3337
{
3438
// Mock DB insert
@@ -47,4 +51,5 @@ public function testInsertInvalidationEventWithAssociations(): void
4751
]
4852
);
4953
}
54+
*/
5055
}

0 commit comments

Comments
 (0)