diff --git a/app/cdash/app/Model/Project.php b/app/cdash/app/Model/Project.php index 207f940cc8..41b3e33977 100644 --- a/app/cdash/app/Model/Project.php +++ b/app/cdash/app/Model/Project.php @@ -30,6 +30,7 @@ use DateTimeZone; use Exception; use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use PDO; @@ -501,6 +502,15 @@ public function CheckForTooManyBuilds(): bool return false; } + // Fetching the exact build count is expensive, so don't do it if it's been less than + // 10 minutes since the last time we checked. While this means build counts can temporarily + // be higher than the limit, it lightens the database load during peak hours. + $cache_key = "check_too_many_builds_project_{$this->Id}"; + if (Cache::has($cache_key)) { + return false; + } + Cache::put($cache_key, true, 10 * 60); + $project = EloquentProject::findOrFail((int) $this->Id); $num_builds = $project->builds()->onlyParents()->count(); diff --git a/app/cdash/tests/test_limitedbuilds.php b/app/cdash/tests/test_limitedbuilds.php index af8eea1551..aba69ded69 100644 --- a/app/cdash/tests/test_limitedbuilds.php +++ b/app/cdash/tests/test_limitedbuilds.php @@ -9,6 +9,7 @@ use CDash\Database; use CDash\Model\Build; use CDash\Model\Project; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; class LimitedBuildsTestCase extends KWWebTestCase @@ -58,14 +59,21 @@ public function testLimitedBuilds(): void $project = App\Models\Project::findOrFail((int) $this->Projects[0]->Id); - // Submit two builds to the 'Limited' project. - // The second submission will cause the first build to get deleted. + // Submit three builds to the 'Limited' project. + // The second submission will not cause the first build to get deleted because it's been + // than 10 minutes since the previous build. Flushing the cache expires the record and + // means submitting the 3rd build will cause the first two to be deleted. $this->submitBuild(1, 'Limited'); $this->assertEqual($project->refresh()->builds()->count(), 1); $this->get_build_stmt->execute([$this->Projects[0]->Id]); $buildid1 = $this->get_build_stmt->fetchColumn(); + $this->submitBuild(2, 'Limited'); + $this->assertEqual($project->refresh()->builds()->count(), 2); + + Cache::flush(); + $this->submitBuild(2, 'Limited'); $this->assertEqual($project->refresh()->builds()->count(), 1); diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 5986c258c6..30b41920af 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -9219,6 +9219,12 @@ parameters: count: 1 path: app/cdash/app/Model/Project.php + - + rawMessage: 'Method CDash\Model\Project::CheckForTooManyBuilds() throws checked exception Psr\SimpleCache\InvalidArgumentException but it''s missing from the PHPDoc @throws tag.' + identifier: missingType.checkedException + count: 1 + path: app/cdash/app/Model/Project.php + - rawMessage: 'Method CDash\Model\Project::ComputeTestingDayBounds() has parameter $date with no type specified.' identifier: missingType.parameter