From 4695c4da19b38b9d32d027d45f77495250fb4e8a Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Fri, 14 Nov 2025 13:55:27 +0100 Subject: [PATCH 1/3] Track metrics related to dblist generation --- extension.json | 4 ++++ includes/ConfigNames.php | 2 ++ includes/Helpers/RemoteWiki.php | 2 +- includes/ServiceWiring.php | 1 + includes/Services/CreateWikiDataStore.php | 25 ++++++++++++++++++++--- includes/Services/WikiManagerFactory.php | 6 +++--- maintenance/ManageInactiveWikis.php | 2 +- 7 files changed, 34 insertions(+), 8 deletions(-) diff --git a/extension.json b/extension.json index 560bee1099..aec3f33c96 100644 --- a/extension.json +++ b/extension.json @@ -416,6 +416,10 @@ "description": "String. The main part of subdomains, e.g. wiki.example.org, example.org is the main part.", "value": "" }, + "CreateWikiTrackDatabaseListMetrics": { + "description": "Boolean. Whether to track metrics related to the (re)generation of database lists.", + "value": false + }, "CreateWikiUseClosedWikis": { "description": "Boolean. Whether to implement front end logic for closing wikis.", "value": false diff --git a/includes/ConfigNames.php b/includes/ConfigNames.php index 48370c99d5..7b7f57711a 100644 --- a/includes/ConfigNames.php +++ b/includes/ConfigNames.php @@ -35,6 +35,8 @@ class ConfigNames { public const EmailNotifications = 'CreateWikiEmailNotifications'; + public const TrackDatabaseListMetrics = 'CreateWikiTrackDatabaseListMetrics'; + public const EnableManageInactiveWikis = 'CreateWikiEnableManageInactiveWikis'; public const EnableRESTAPI = 'CreateWikiEnableRESTAPI'; diff --git a/includes/Helpers/RemoteWiki.php b/includes/Helpers/RemoteWiki.php index 6e983ffdac..7468e9dad6 100644 --- a/includes/Helpers/RemoteWiki.php +++ b/includes/Helpers/RemoteWiki.php @@ -470,7 +470,7 @@ public function commit(): void { } if ( $this->resetDatabaseLists ) { - $this->dataStore->resetDatabaseLists( isNewChanges: true ); + $this->dataStore->resetDatabaseLists( isNewChanges: true, caller: __METHOD__ ); } $this->hookRunner->onCreateWikiRemoteWikiCommit( $this->dbname ); diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index c75c98eef4..98595bdb13 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -34,6 +34,7 @@ 'CreateWikiDataStore' => static function ( MediaWikiServices $services ): CreateWikiDataStore { return new CreateWikiDataStore( $services->getObjectCacheFactory(), + $services->getStatsFactory(), $services->get( 'CreateWikiDatabaseUtils' ), $services->get( 'CreateWikiHookRunner' ), new ServiceOptions( diff --git a/includes/Services/CreateWikiDataStore.php b/includes/Services/CreateWikiDataStore.php index 283f8981d8..0c43326a63 100644 --- a/includes/Services/CreateWikiDataStore.php +++ b/includes/Services/CreateWikiDataStore.php @@ -12,6 +12,7 @@ use Wikimedia\ObjectCache\BagOStuff; use Wikimedia\Rdbms\IReadableDatabase; use Wikimedia\StaticArrayWriter; +use Wikimedia\Stats\StatsFactory; use function array_keys; use function file_put_contents; use function function_exists; @@ -28,6 +29,7 @@ class CreateWikiDataStore { public const CONSTRUCTOR_OPTIONS = [ ConfigNames::CacheDirectory, ConfigNames::CacheType, + ConfigNames::TrackDatabaseListMetrics, MainConfigNames::CacheDirectory, MainConfigNames::LocalDatabases, ]; @@ -41,9 +43,11 @@ class CreateWikiDataStore { private readonly string $cacheDir; private int $timestamp; private int $localServerTimestamp; + private readonly bool $trackDatabaseListMetrics; public function __construct( ObjectCacheFactory $objectCacheFactory, + private readonly StatsFactory $statsFactory, private readonly CreateWikiDatabaseUtils $databaseUtils, private readonly CreateWikiHookRunner $hookRunner, private readonly ServiceOptions $options @@ -64,6 +68,8 @@ public function __construct( $this->localServerTimestamp = (int)$this->localServerCache->get( $this->localServerCache->makeGlobalKey( self::CACHE_KEY, 'databases-local' ) ); + + $this->trackDatabaseListMetrics = $this->options->get( ConfigNames::TrackDatabaseListMetrics ); } /** @@ -73,7 +79,7 @@ public function __construct( */ public function syncCache(): void { if ( !$this->timestamp ) { - $this->resetDatabaseLists( isNewChanges: true ); + $this->resetDatabaseLists( isNewChanges: true, caller: __METHOD__ ); return; } @@ -86,7 +92,7 @@ public function syncCache(): void { // Only regenerate if localServerTimestamp is smaller than timestamp so multiple processes on the // same server don't try regenerating the dblists at the same time. if ( ( $mtime === 0 || $mtime < $this->timestamp ) && $this->localServerTimestamp < $this->timestamp ) { - $this->resetDatabaseLists( isNewChanges: false ); + $this->resetDatabaseLists( isNewChanges: false, caller: __METHOD__ ); } } @@ -105,7 +111,18 @@ public function getAllDatabases(): array { * the updated list to a PHP file within the cache directory. It also updates the * modification time (mtime) and stores it in the cache for future reference. */ - public function resetDatabaseLists( bool $isNewChanges ): void { + public function resetDatabaseLists( bool $isNewChanges, string $caller = 'unknown' ): void { + $timer = null; + if ( $this->trackDatabaseListMetrics ) { + $this->statsFactory->getCounter( 'createwiki_dblist_generation_total' ) + ->setLabel( 'cause', $caller ) + ->setLabel( 'new_changes', $isNewChanges ) + ->increment(); + + $timer = $this->statsFactory->getTiming( 'createwiki_dblist_generation_seconds' ) + ->start(); + } + $mtime = time(); $this->localServerCache->set( $this->localServerCache->makeGlobalKey( self::CACHE_KEY, 'databases-local' ), @@ -132,6 +149,7 @@ public function resetDatabaseLists( bool $isNewChanges ): void { $this->writeToFile( $name, $list ); } + $timer?->stop(); return; } @@ -171,6 +189,7 @@ public function resetDatabaseLists( bool $isNewChanges ): void { ]; $this->writeToFile( 'databases', $list ); + $timer?->stop(); } /** diff --git a/includes/Services/WikiManagerFactory.php b/includes/Services/WikiManagerFactory.php index f8c96d7a46..c3cd5b0dec 100644 --- a/includes/Services/WikiManagerFactory.php +++ b/includes/Services/WikiManagerFactory.php @@ -268,7 +268,7 @@ private function doAfterCreate( DeferredUpdates::addCallableUpdate( function () use ( $requester, $extra ) { - $this->dataStore->resetDatabaseLists( isNewChanges: true ); + $this->dataStore->resetDatabaseLists( isNewChanges: true, caller: __METHOD__ ); $limits = [ 'memory' => 0, 'filesize' => 0, 'time' => 0, 'walltime' => 0 ]; Shell::makeScriptCommand( @@ -383,7 +383,7 @@ public function delete( bool $force ): ?string { ->execute(); } - $this->dataStore->resetDatabaseLists( isNewChanges: true ); + $this->dataStore->resetDatabaseLists( isNewChanges: true, caller: __METHOD__ ); $this->hookRunner->onCreateWikiDeletion( $this->cwdb, $this->dbname ); return null; @@ -417,7 +417,7 @@ public function rename( string $newDatabaseName ): ?string { ->execute(); } - $this->dataStore->resetDatabaseLists( isNewChanges: true ); + $this->dataStore->resetDatabaseLists( isNewChanges: true, caller: __METHOD__ ); $this->hookRunner->onCreateWikiRename( $this->cwdb, $this->dbname, $newDatabaseName ); return null; diff --git a/maintenance/ManageInactiveWikis.php b/maintenance/ManageInactiveWikis.php index 5b596620d3..35e3dd139e 100644 --- a/maintenance/ManageInactiveWikis.php +++ b/maintenance/ManageInactiveWikis.php @@ -77,7 +77,7 @@ public function execute(): void { } } - $this->dataStore->resetDatabaseLists( isNewChanges: true ); + $this->dataStore->resetDatabaseLists( isNewChanges: true, caller: __METHOD__ ); } private function checkLastActivity( From 52823a27b8e33c204153633991672e3cef778e05 Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Fri, 14 Nov 2025 14:06:11 +0100 Subject: [PATCH 2/3] fix phan errors --- includes/Services/CreateWikiDataStore.php | 8 +++++--- includes/Services/WikiManagerFactory.php | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/includes/Services/CreateWikiDataStore.php b/includes/Services/CreateWikiDataStore.php index 0c43326a63..e9354562fc 100644 --- a/includes/Services/CreateWikiDataStore.php +++ b/includes/Services/CreateWikiDataStore.php @@ -111,14 +111,16 @@ public function getAllDatabases(): array { * the updated list to a PHP file within the cache directory. It also updates the * modification time (mtime) and stores it in the cache for future reference. */ - public function resetDatabaseLists( bool $isNewChanges, string $caller = 'unknown' ): void { + public function resetDatabaseLists( bool $isNewChanges, ?string $caller = null ): void { $timer = null; if ( $this->trackDatabaseListMetrics ) { + /** @phan-suppress-next-line PhanPossiblyUndeclaredMethod */ $this->statsFactory->getCounter( 'createwiki_dblist_generation_total' ) - ->setLabel( 'cause', $caller ) - ->setLabel( 'new_changes', $isNewChanges ) + ->setLabel( 'cause', $caller ?? 'unknown' ) + ->setLabel( 'new_changes', $isNewChanges ? 'Yes' : 'No' ) ->increment(); + /** @phan-suppress-next-line PhanPossiblyUndeclaredMethod */ $timer = $this->statsFactory->getTiming( 'createwiki_dblist_generation_seconds' ) ->start(); } diff --git a/includes/Services/WikiManagerFactory.php b/includes/Services/WikiManagerFactory.php index c3cd5b0dec..228352c777 100644 --- a/includes/Services/WikiManagerFactory.php +++ b/includes/Services/WikiManagerFactory.php @@ -266,9 +266,10 @@ private function doAfterCreate( $this->hookRunner->onCreateWikiCreation( $this->dbname, $private ); + $method = __METHOD__; DeferredUpdates::addCallableUpdate( - function () use ( $requester, $extra ) { - $this->dataStore->resetDatabaseLists( isNewChanges: true, caller: __METHOD__ ); + function () use ( $requester, $extra, $method ) { + $this->dataStore->resetDatabaseLists( isNewChanges: true, caller: $method ); $limits = [ 'memory' => 0, 'filesize' => 0, 'time' => 0, 'walltime' => 0 ]; Shell::makeScriptCommand( From 5732924aab7727d3004202110fdc92ceb42ce8cb Mon Sep 17 00:00:00 2001 From: SomeRandomDeveloper Date: Fri, 14 Nov 2025 14:27:39 +0100 Subject: [PATCH 3/3] fix phan again --- includes/Services/CreateWikiDataStore.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Services/CreateWikiDataStore.php b/includes/Services/CreateWikiDataStore.php index e9354562fc..a518ba30cc 100644 --- a/includes/Services/CreateWikiDataStore.php +++ b/includes/Services/CreateWikiDataStore.php @@ -111,6 +111,7 @@ public function getAllDatabases(): array { * the updated list to a PHP file within the cache directory. It also updates the * modification time (mtime) and stores it in the cache for future reference. */ + // @phan-suppress-next-line PhanDisallowedOptionalMethodParameter public function resetDatabaseLists( bool $isNewChanges, ?string $caller = null ): void { $timer = null; if ( $this->trackDatabaseListMetrics ) { @@ -120,7 +121,6 @@ public function resetDatabaseLists( bool $isNewChanges, ?string $caller = null ) ->setLabel( 'new_changes', $isNewChanges ? 'Yes' : 'No' ) ->increment(); - /** @phan-suppress-next-line PhanPossiblyUndeclaredMethod */ $timer = $this->statsFactory->getTiming( 'createwiki_dblist_generation_seconds' ) ->start(); }