diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index e0915e93..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; diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index e3c601c5..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(); @@ -72,4 +80,47 @@ public function testRunJobForAllWikisIncludingDeletedWikis() { 'entity_schema_count' => 0, ]); } + + public function testRunningJobTwiceForSameWikiWithChangedValuesSkipsSecondRunWhenRecordExistsForToday() { + $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' => 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()); + }); + } }