From 8a0f952453c3e9a2fc154d18f7c8db81cb7293b0 Mon Sep 17 00:00:00 2001 From: Celeo Date: Mon, 27 Jul 2026 13:16:32 -0700 Subject: [PATCH] Restrict moodle:sync bulk pass to recently-active users The bulk pass scans the entire users table every 3 hours with no activity filter, driving Moodle's cohort/role writes hard enough to trigger cacherev lock contention (see PRs #114/#115's diff-based rewrite, which cut write volume but didn't bound the scan itself). Users who haven't logged in in months have no pending facility/rating/ staff-role changes to reconcile, so there's no reason to keep including them as the table keeps growing. New-controller Observer cohort onboarding no longer depends on this job at all -- that's now handled at login time in cobalt (see companion cobalt PR) -- so narrowing this job's scope doesn't affect onboarding latency, only reduces backstop maintenance-sync volume. Co-Authored-By: Claude Sonnet 5 --- app/Console/Commands/MoodleSync.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/MoodleSync.php b/app/Console/Commands/MoodleSync.php index 79f0a5a..aeec48a 100644 --- a/app/Console/Commands/MoodleSync.php +++ b/app/Console/Commands/MoodleSync.php @@ -42,6 +42,16 @@ class MoodleSync extends Command * low enough for Moodle's DB to keep up. */ private const FLUSH_PACING_USEC = 300000; + /** @var int The bulk pass only needs to maintain cohorts/roles for users who could + * plausibly still need a change (facility/rating/staff-role updates) — + * there's no reason to re-diff someone who hasn't logged into the site in + * months. Restricting to recently-active users keeps the per-run row count + * (and therefore Moodle write volume / cacherev contention) bounded as the + * full user table keeps growing, on top of the diff-based writes from + * computeSyncItems(). New-controller onboarding doesn't depend on this + * filter: that's handled at login time (see cobalt's syncMoodleCohort). */ + private const ACTIVE_WITHIN_DAYS = 90; + /** * Create a new command instance. * @@ -78,13 +88,17 @@ public function handle() //Syncronize Users $moodleIds = $this->moodle->getAllUserIdMap(); $cohortIdMap = $this->moodle->getCohortIdMap(); - logger()->info("moodle:sync starting bulk pass: {$moodleIds->count()} Moodle-linked users"); + $activeSince = now()->subDays(self::ACTIVE_WITHIN_DAYS); + logger()->info("moodle:sync starting bulk pass: {$moodleIds->count()} Moodle-linked users, " . + "restricted to lastactivity >= {$activeSince->toDateString()}"); $chunkNum = 0; $totals = ['users' => 0, 'cohortAdds' => 0, 'cohortRemoves' => 0, 'roleAdds' => 0, 'roleRemoves' => 0, 'enrolments' => 0, 'failedBatches' => 0]; - User::with('visits', 'academyCompetencies.course', 'roles')->chunk(1000, + User::with('visits', 'academyCompetencies.course', 'roles') + ->where('lastactivity', '>=', $activeSince) + ->chunk(1000, function ($users) use ($moodleIds, $cohortIdMap, &$chunkNum, &$totals) { $chunkNum++;