From b1cfbf2718b758b4528e531ea84065e807328afe Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:24:43 +0200 Subject: [PATCH 01/17] Add test to catch duplicate keys errors --- tests/Jobs/UpdateWikiDailyMetricJobTest.php | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index e3c601c5..91df1bc5 100644 --- a/tests/Jobs/UpdateWikiDailyMetricJobTest.php +++ b/tests/Jobs/UpdateWikiDailyMetricJobTest.php @@ -72,4 +72,39 @@ public function testRunJobForAllWikisIncludingDeletedWikis() { 'entity_schema_count' => 0, ]); } + + public function testRunningJobTwiceForSameWikiWithChangedValuesCreatesOnlyOneDailyRecord() { + $wiki = Wiki::factory()->create([ + 'domain' => 'duplicate.wikibase.cloud', + ]); + + $manager = $this->app->make('db'); + $job = new ProvisionWikiDbJob(); + $job->handle($manager); + + $wikiDb = WikiDb::whereDoesntHave('wiki')->first(); + $wikiDb->update(['wiki_id' => $wiki->id]); + + $wiki->wikiSiteStats()->create([ + 'pages' => 10, + 'users' => 3, + ]); + + $dailyMetricJob = new UpdateWikiDailyMetricJob(); + $dailyMetricJob->handle(); + + $wiki->wikiSiteStats()->first()->update([ + 'pages' => 12, + 'users' => 5, + ]); + + $dailyMetricJob->handle(); + + $this->assertDatabaseCount('wiki_daily_metrics', 1) + ->assertDatabaseHas('wiki_daily_metrics', [ + 'wiki_id' => $wiki->id, + 'date' => Carbon::today()->toDateString(), + 'pages' => 12, + ]); + } } From 353aa1d86ec48da1cdc39524ee3d99c11482ec46 Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:25:18 +0200 Subject: [PATCH 02/17] Add withoutOverlapping() to UpdateWikiDailyMetricJob --- app/Console/Kernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index cca1f77a..90d7a0f9 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -57,7 +57,7 @@ protected function schedule(Schedule $schedule): void { $schedule->job(new SendEmptyWikiNotificationsJob())->dailyAt('21:00'); - $schedule->job(new UpdateWikiDailyMetricJob())->dailyAt('23:00'); + $schedule->job(new UpdateWikiDailyMetricJob())->dailyAt('23:00')->withoutOverlapping(); $schedule->job(new UpdateQueryserviceAllowList())->weeklyOn(Schedule::MONDAY, '01:00'); From 64f4c97301fb89d3c880926eebc74350b7656f04 Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:28:28 +0200 Subject: [PATCH 03/17] add daily metric write idempotent guard --- app/Metrics/App/WikiMetrics.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index e0915e93..d5f2bf7d 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -57,6 +57,26 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); + // check if a record already exists for this wiki and date + $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) + ->where('date', $today) + ->first(); + + if ($existingRecord) { + if ($existingRecord->areMetricsEqual($dailyMetrics)) { + Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); + + return; + } + + $existingRecord->fill($dailyMetrics->toArray()); + $existingRecord->save(); + + Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); + + return; + } + // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From d50c2f453eb3edac079944272df323d35d0f45ee Mon Sep 17 00:00:00 2001 From: Dat Date: Thu, 24 Sep 2026 11:44:45 +0200 Subject: [PATCH 04/17] rename and adjust the test to match new behavior --- tests/Jobs/UpdateWikiDailyMetricJobTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index 91df1bc5..6706c284 100644 --- a/tests/Jobs/UpdateWikiDailyMetricJobTest.php +++ b/tests/Jobs/UpdateWikiDailyMetricJobTest.php @@ -73,7 +73,7 @@ public function testRunJobForAllWikisIncludingDeletedWikis() { ]); } - public function testRunningJobTwiceForSameWikiWithChangedValuesCreatesOnlyOneDailyRecord() { + public function testRunningJobTwiceForSameWikiWithChangedValuesSkipsSecondRunWhenRecordExistsForToday() { $wiki = Wiki::factory()->create([ 'domain' => 'duplicate.wikibase.cloud', ]); @@ -104,7 +104,7 @@ public function testRunningJobTwiceForSameWikiWithChangedValuesCreatesOnlyOneDai ->assertDatabaseHas('wiki_daily_metrics', [ 'wiki_id' => $wiki->id, 'date' => Carbon::today()->toDateString(), - 'pages' => 12, + 'pages' => 10, ]); } } From 9790df5b667065f8cb3d9dffe612afcdee3b983c Mon Sep 17 00:00:00 2001 From: Dat Date: Thu, 24 Sep 2026 11:45:11 +0200 Subject: [PATCH 05/17] Add early record existence check --- app/Metrics/App/WikiMetrics.php | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index d5f2bf7d..dd5ca72d 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -25,6 +25,18 @@ public function saveMetrics(Wiki $wiki): void { $this->wiki = $wiki; $today = now()->format('Y-m-d'); + + // Skip expensive metrics collection if today's record already exists. + $recordExists = WikiDailyMetrics::where('wiki_id', $wiki->id) + ->where('date', $today) + ->exists(); + + if ($recordExists) { + Log::warning("Daily metric already exists for Wiki ID {$wiki->id} on {$today}; skipping metrics collection."); + + return; + } + $tripleCount = $this->getNumOfTriples(); $todayPageCount = $wiki->wikiSiteStats()->first()->pages ?? 0; $isDeleted = (bool) $wiki->deleted_at; @@ -57,26 +69,6 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); - // check if a record already exists for this wiki and date - $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) - ->where('date', $today) - ->first(); - - if ($existingRecord) { - if ($existingRecord->areMetricsEqual($dailyMetrics)) { - Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); - - return; - } - - $existingRecord->fill($dailyMetrics->toArray()); - $existingRecord->save(); - - Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); - - return; - } - // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From f6e3de3567b506a33ec6616acbf482200085a41a Mon Sep 17 00:00:00 2001 From: Dat Date: Tue, 29 Sep 2026 14:42:12 +0200 Subject: [PATCH 06/17] Add test to be sure the warning is logged when there is a record already --- tests/Jobs/UpdateWikiDailyMetricJobTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index 6706c284..e0699546 100644 --- a/tests/Jobs/UpdateWikiDailyMetricJobTest.php +++ b/tests/Jobs/UpdateWikiDailyMetricJobTest.php @@ -8,12 +8,20 @@ use App\WikiDb; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Queue; use Tests\TestCase; +use TiMacDonald\Log\LogEntry; +use TiMacDonald\Log\LogFake; class UpdateWikiDailyMetricJobTest extends TestCase { use RefreshDatabase; + protected function setUp(): void { + parent::setUp(); + Log::swap(new LogFake()); + } + public function testDispatchJob() { Queue::fake(); @@ -106,5 +114,13 @@ public function testRunningJobTwiceForSameWikiWithChangedValuesSkipsSecondRunWhe 'date' => Carbon::today()->toDateString(), 'pages' => 10, ]); + + Log::assertLogged(function (LogEntry $log) use ($wiki) { + if ($log->level !== 'warning') { + return false; + } + + return str_contains($log->message, "Daily metric already exists for Wiki ID {$wiki->id} on " . Carbon::today()->toDateString()); + }); } } From 4fce7484194b60f531b9127eac7618b4008da0f4 Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:28:28 +0200 Subject: [PATCH 07/17] add daily metric write idempotent guard --- app/Metrics/App/WikiMetrics.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index dd5ca72d..bb37fb1a 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -69,6 +69,26 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); + // check if a record already exists for this wiki and date + $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) + ->where('date', $today) + ->first(); + + if ($existingRecord) { + if ($existingRecord->areMetricsEqual($dailyMetrics)) { + Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); + + return; + } + + $existingRecord->fill($dailyMetrics->toArray()); + $existingRecord->save(); + + Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); + + return; + } + // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From 74bebe751ffa14f84de47ed43a0dbb5c1ec67ec6 Mon Sep 17 00:00:00 2001 From: Dat Date: Thu, 24 Sep 2026 11:45:11 +0200 Subject: [PATCH 08/17] Add early record existence check --- app/Metrics/App/WikiMetrics.php | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index bb37fb1a..dd5ca72d 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -69,26 +69,6 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); - // check if a record already exists for this wiki and date - $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) - ->where('date', $today) - ->first(); - - if ($existingRecord) { - if ($existingRecord->areMetricsEqual($dailyMetrics)) { - Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); - - return; - } - - $existingRecord->fill($dailyMetrics->toArray()); - $existingRecord->save(); - - Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); - - return; - } - // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From 661985c577110bcb26d2678e50a42f489b584532 Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:24:43 +0200 Subject: [PATCH 09/17] Add test to catch duplicate keys errors --- tests/Jobs/UpdateWikiDailyMetricJobTest.php | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index e3c601c5..91df1bc5 100644 --- a/tests/Jobs/UpdateWikiDailyMetricJobTest.php +++ b/tests/Jobs/UpdateWikiDailyMetricJobTest.php @@ -72,4 +72,39 @@ public function testRunJobForAllWikisIncludingDeletedWikis() { 'entity_schema_count' => 0, ]); } + + public function testRunningJobTwiceForSameWikiWithChangedValuesCreatesOnlyOneDailyRecord() { + $wiki = Wiki::factory()->create([ + 'domain' => 'duplicate.wikibase.cloud', + ]); + + $manager = $this->app->make('db'); + $job = new ProvisionWikiDbJob(); + $job->handle($manager); + + $wikiDb = WikiDb::whereDoesntHave('wiki')->first(); + $wikiDb->update(['wiki_id' => $wiki->id]); + + $wiki->wikiSiteStats()->create([ + 'pages' => 10, + 'users' => 3, + ]); + + $dailyMetricJob = new UpdateWikiDailyMetricJob(); + $dailyMetricJob->handle(); + + $wiki->wikiSiteStats()->first()->update([ + 'pages' => 12, + 'users' => 5, + ]); + + $dailyMetricJob->handle(); + + $this->assertDatabaseCount('wiki_daily_metrics', 1) + ->assertDatabaseHas('wiki_daily_metrics', [ + 'wiki_id' => $wiki->id, + 'date' => Carbon::today()->toDateString(), + 'pages' => 12, + ]); + } } From f7cc51efeb5bc58e0347c27681bae5eb6f5a33b9 Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:25:18 +0200 Subject: [PATCH 10/17] Add withoutOverlapping() to UpdateWikiDailyMetricJob --- app/Console/Kernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index cca1f77a..90d7a0f9 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -57,7 +57,7 @@ protected function schedule(Schedule $schedule): void { $schedule->job(new SendEmptyWikiNotificationsJob())->dailyAt('21:00'); - $schedule->job(new UpdateWikiDailyMetricJob())->dailyAt('23:00'); + $schedule->job(new UpdateWikiDailyMetricJob())->dailyAt('23:00')->withoutOverlapping(); $schedule->job(new UpdateQueryserviceAllowList())->weeklyOn(Schedule::MONDAY, '01:00'); From 53181544ab5e1ef510ee35735ca5c6f200f1023c Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:28:28 +0200 Subject: [PATCH 11/17] add daily metric write idempotent guard --- app/Metrics/App/WikiMetrics.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index e0915e93..d5f2bf7d 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -57,6 +57,26 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); + // check if a record already exists for this wiki and date + $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) + ->where('date', $today) + ->first(); + + if ($existingRecord) { + if ($existingRecord->areMetricsEqual($dailyMetrics)) { + Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); + + return; + } + + $existingRecord->fill($dailyMetrics->toArray()); + $existingRecord->save(); + + Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); + + return; + } + // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From 447ceb52ee2a23409a7b47bd0315a495dd9d1fc2 Mon Sep 17 00:00:00 2001 From: Dat Date: Thu, 24 Sep 2026 11:44:45 +0200 Subject: [PATCH 12/17] rename and adjust the test to match new behavior --- tests/Jobs/UpdateWikiDailyMetricJobTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index 91df1bc5..6706c284 100644 --- a/tests/Jobs/UpdateWikiDailyMetricJobTest.php +++ b/tests/Jobs/UpdateWikiDailyMetricJobTest.php @@ -73,7 +73,7 @@ public function testRunJobForAllWikisIncludingDeletedWikis() { ]); } - public function testRunningJobTwiceForSameWikiWithChangedValuesCreatesOnlyOneDailyRecord() { + public function testRunningJobTwiceForSameWikiWithChangedValuesSkipsSecondRunWhenRecordExistsForToday() { $wiki = Wiki::factory()->create([ 'domain' => 'duplicate.wikibase.cloud', ]); @@ -104,7 +104,7 @@ public function testRunningJobTwiceForSameWikiWithChangedValuesCreatesOnlyOneDai ->assertDatabaseHas('wiki_daily_metrics', [ 'wiki_id' => $wiki->id, 'date' => Carbon::today()->toDateString(), - 'pages' => 12, + 'pages' => 10, ]); } } From c54fffe1e117ee774fbf96fe406d6b1c95ce15f2 Mon Sep 17 00:00:00 2001 From: Dat Date: Thu, 24 Sep 2026 11:45:11 +0200 Subject: [PATCH 13/17] Add early record existence check --- app/Metrics/App/WikiMetrics.php | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index d5f2bf7d..dd5ca72d 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -25,6 +25,18 @@ public function saveMetrics(Wiki $wiki): void { $this->wiki = $wiki; $today = now()->format('Y-m-d'); + + // Skip expensive metrics collection if today's record already exists. + $recordExists = WikiDailyMetrics::where('wiki_id', $wiki->id) + ->where('date', $today) + ->exists(); + + if ($recordExists) { + Log::warning("Daily metric already exists for Wiki ID {$wiki->id} on {$today}; skipping metrics collection."); + + return; + } + $tripleCount = $this->getNumOfTriples(); $todayPageCount = $wiki->wikiSiteStats()->first()->pages ?? 0; $isDeleted = (bool) $wiki->deleted_at; @@ -57,26 +69,6 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); - // check if a record already exists for this wiki and date - $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) - ->where('date', $today) - ->first(); - - if ($existingRecord) { - if ($existingRecord->areMetricsEqual($dailyMetrics)) { - Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); - - return; - } - - $existingRecord->fill($dailyMetrics->toArray()); - $existingRecord->save(); - - Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); - - return; - } - // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From c3e2a64dbf1ee354a131f0cd6c54f2737149837d Mon Sep 17 00:00:00 2001 From: Dat Date: Tue, 29 Sep 2026 14:42:12 +0200 Subject: [PATCH 14/17] Add test to be sure the warning is logged when there is a record already --- tests/Jobs/UpdateWikiDailyMetricJobTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index 6706c284..e0699546 100644 --- a/tests/Jobs/UpdateWikiDailyMetricJobTest.php +++ b/tests/Jobs/UpdateWikiDailyMetricJobTest.php @@ -8,12 +8,20 @@ use App\WikiDb; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Queue; use Tests\TestCase; +use TiMacDonald\Log\LogEntry; +use TiMacDonald\Log\LogFake; class UpdateWikiDailyMetricJobTest extends TestCase { use RefreshDatabase; + protected function setUp(): void { + parent::setUp(); + Log::swap(new LogFake()); + } + public function testDispatchJob() { Queue::fake(); @@ -106,5 +114,13 @@ public function testRunningJobTwiceForSameWikiWithChangedValuesSkipsSecondRunWhe 'date' => Carbon::today()->toDateString(), 'pages' => 10, ]); + + Log::assertLogged(function (LogEntry $log) use ($wiki) { + if ($log->level !== 'warning') { + return false; + } + + return str_contains($log->message, "Daily metric already exists for Wiki ID {$wiki->id} on " . Carbon::today()->toDateString()); + }); } } From ae0aaac31f245c616a7a532c47a93cd0cbfb9d18 Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 23 Sep 2026 14:28:28 +0200 Subject: [PATCH 15/17] add daily metric write idempotent guard --- app/Metrics/App/WikiMetrics.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index dd5ca72d..bb37fb1a 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -69,6 +69,26 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); + // check if a record already exists for this wiki and date + $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) + ->where('date', $today) + ->first(); + + if ($existingRecord) { + if ($existingRecord->areMetricsEqual($dailyMetrics)) { + Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); + + return; + } + + $existingRecord->fill($dailyMetrics->toArray()); + $existingRecord->save(); + + Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); + + return; + } + // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From 3ac45dc594c90c1433d833de2b915cf7ec2b0627 Mon Sep 17 00:00:00 2001 From: Dat Date: Thu, 24 Sep 2026 11:45:11 +0200 Subject: [PATCH 16/17] Add early record existence check --- app/Metrics/App/WikiMetrics.php | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index bb37fb1a..dd5ca72d 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -69,26 +69,6 @@ public function saveMetrics(Wiki $wiki): void { 'total_user_count' => $numberOfUsers, ]); - // check if a record already exists for this wiki and date - $existingRecord = WikiDailyMetrics::where('wiki_id', $wiki->id) - ->where('date', $today) - ->first(); - - if ($existingRecord) { - if ($existingRecord->areMetricsEqual($dailyMetrics)) { - Log::info("Record unchanged for Wiki ID {$wiki->id} on {$today}, no update needed."); - - return; - } - - $existingRecord->fill($dailyMetrics->toArray()); - $existingRecord->save(); - - Log::info("Updated daily metric for Wiki ID {$wiki->id} on {$today}"); - - return; - } - // compare current record to previous record and only save if there is a change $previousRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); if ($previousRecord?->areMetricsEqual($dailyMetrics)) { From 4791151c4b42bdd9a3168be4aaa1addc6a0cc8cc Mon Sep 17 00:00:00 2001 From: Dat Date: Wed, 30 Sep 2026 12:12:07 +0200 Subject: [PATCH 17/17] Remove withoutOverlapping() --- app/Console/Kernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 90d7a0f9..cca1f77a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -57,7 +57,7 @@ protected function schedule(Schedule $schedule): void { $schedule->job(new SendEmptyWikiNotificationsJob())->dailyAt('21:00'); - $schedule->job(new UpdateWikiDailyMetricJob())->dailyAt('23:00')->withoutOverlapping(); + $schedule->job(new UpdateWikiDailyMetricJob())->dailyAt('23:00'); $schedule->job(new UpdateQueryserviceAllowList())->weeklyOn(Schedule::MONDAY, '01:00');