From ed1195ea23bb214f7f7c433f49f634c9df29ebf4 Mon Sep 17 00:00:00 2001 From: Daimona Eaytoy Date: Sun, 29 Nov 2020 00:53:42 +0100 Subject: [PATCH] Add UpdateHitCountWatcher Change-Id: I61c40312022c1037abb03819d06e5e220dd07e15 --- includes/AbuseFilterRunner.php | 36 ++---------- includes/AbuseFilterServices.php | 8 +++ includes/ServiceWiring.php | 7 +++ includes/Watcher/EmergencyWatcher.php | 4 +- includes/Watcher/UpdateHitCountWatcher.php | 64 ++++++++++++++++++++++ includes/Watcher/Watcher.php | 5 +- 6 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 includes/Watcher/UpdateHitCountWatcher.php diff --git a/includes/AbuseFilterRunner.php b/includes/AbuseFilterRunner.php index 2fd4cd0e2..1db267185 100644 --- a/includes/AbuseFilterRunner.php +++ b/includes/AbuseFilterRunner.php @@ -15,7 +15,6 @@ use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGenerator; use MediaWiki\Extension\AbuseFilter\Watcher\Watcher; use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; -use Wikimedia\Rdbms\IDatabase; /** * This class contains the logic for executing abuse filters and their actions. The entry points are @@ -109,7 +108,10 @@ class AbuseFilterRunner { $this->changeTagger = AbuseFilterServices::getChangeTagger(); $this->filterLookup = AbuseFilterServices::getFilterLookup(); // TODO Inject, add a hook for custom watchers - $this->watchers = [ AbuseFilterServices::getEmergencyWatcher() ]; + $this->watchers = [ + AbuseFilterServices::getUpdateHitCountWatcher(), + AbuseFilterServices::getEmergencyWatcher() + ]; } /** @@ -237,17 +239,8 @@ class AbuseFilterRunner { 'global' => $loggedGlobalFilters ] = $abuseLogger->addLogEntries( $actionsTaken ); - if ( count( $loggedLocalFilters ) ) { - $this->updateHitCounts( wfGetDB( DB_MASTER ), $loggedLocalFilters ); - } - - if ( count( $loggedGlobalFilters ) ) { - $fdb = AbuseFilterServices::getCentralDBManager()->getConnection( DB_MASTER ); - $this->updateHitCounts( $fdb, $loggedGlobalFilters ); - } - foreach ( $this->watchers as $watcher ) { - $watcher->run( $loggedLocalFilters, $this->group ); + $watcher->run( $loggedLocalFilters, $loggedGlobalFilters, $this->group ); } return $status; @@ -734,25 +727,6 @@ class AbuseFilterRunner { return $status; } - /** - * @param IDatabase $dbw - * @param array $loggedFilters - * @todo Move to a Watcher - */ - private function updateHitCounts( IDatabase $dbw, array $loggedFilters ) : void { - $method = __METHOD__; - $dbw->onTransactionPreCommitOrIdle( - function () use ( $dbw, $loggedFilters, $method ) { - $dbw->update( 'abuse_filter', - [ 'af_hit_count=af_hit_count+1' ], - [ 'af_id' => $loggedFilters ], - $method - ); - }, - $method - ); - } - /** * @return array */ diff --git a/includes/AbuseFilterServices.php b/includes/AbuseFilterServices.php index a6b4a251c..899ff77ca 100644 --- a/includes/AbuseFilterServices.php +++ b/includes/AbuseFilterServices.php @@ -7,6 +7,7 @@ use MediaWiki\Extension\AbuseFilter\ChangeTags\ChangeTagsManager; use MediaWiki\Extension\AbuseFilter\ChangeTags\ChangeTagValidator; use MediaWiki\Extension\AbuseFilter\Parser\ParserFactory; use MediaWiki\Extension\AbuseFilter\Watcher\EmergencyWatcher; +use MediaWiki\Extension\AbuseFilter\Watcher\UpdateHitCountWatcher; use MediaWiki\MediaWikiServices; class AbuseFilterServices { @@ -150,4 +151,11 @@ class AbuseFilterServices { public static function getAbuseLoggerFactory() : AbuseLoggerFactory { return MediaWikiServices::getInstance()->getService( AbuseLoggerFactory::SERVICE_NAME ); } + + /** + * @return UpdateHitCountWatcher + */ + public static function getUpdateHitCountWatcher() : UpdateHitCountWatcher { + return MediaWikiServices::getInstance()->getService( UpdateHitCountWatcher::SERVICE_NAME ); + } } diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 39a143458..8f6891cbc 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -23,6 +23,7 @@ use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner; use MediaWiki\Extension\AbuseFilter\KeywordsManager; use MediaWiki\Extension\AbuseFilter\Parser\ParserFactory; use MediaWiki\Extension\AbuseFilter\Watcher\EmergencyWatcher; +use MediaWiki\Extension\AbuseFilter\Watcher\UpdateHitCountWatcher; use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use MediaWiki\Session\SessionManager; @@ -196,6 +197,12 @@ return [ RequestContext::getMain()->getRequest()->getIP() ); }, + UpdateHitCountWatcher::SERVICE_NAME => function ( MediaWikiServices $services ): UpdateHitCountWatcher { + return new UpdateHitCountWatcher( + $services->getDBLoadBalancer(), + $services->get( CentralDBManager::SERVICE_NAME ) + ); + }, ]; // @codeCoverageIgnoreEnd diff --git a/includes/Watcher/EmergencyWatcher.php b/includes/Watcher/EmergencyWatcher.php index 3ed23a59d..16faad88e 100644 --- a/includes/Watcher/EmergencyWatcher.php +++ b/includes/Watcher/EmergencyWatcher.php @@ -116,8 +116,8 @@ class EmergencyWatcher implements Watcher { * * @inheritDoc */ - public function run( array $filters, string $group ) : void { - $throttleFilters = $this->getFiltersToThrottle( $filters, $group ); + public function run( array $localFilters, array $globalFilters, string $group ) : void { + $throttleFilters = $this->getFiltersToThrottle( $localFilters, $group ); if ( !$throttleFilters ) { return; } diff --git a/includes/Watcher/UpdateHitCountWatcher.php b/includes/Watcher/UpdateHitCountWatcher.php new file mode 100644 index 000000000..25e565761 --- /dev/null +++ b/includes/Watcher/UpdateHitCountWatcher.php @@ -0,0 +1,64 @@ +loadBalancer = $loadBalancer; + $this->centralDBManager = $centralDBManager; + } + + /** + * @inheritDoc + */ + public function run( array $localFilters, array $globalFilters, string $group ) : void { + if ( count( $localFilters ) ) { + $this->updateHitCounts( $this->loadBalancer->getConnectionRef( DB_MASTER ), $localFilters ); + } + + if ( count( $globalFilters ) ) { + $fdb = $this->centralDBManager->getConnection( DB_MASTER ); + $this->updateHitCounts( $fdb, $globalFilters ); + } + } + + /** + * @param IDatabase $dbw + * @param array $loggedFilters + */ + private function updateHitCounts( IDatabase $dbw, array $loggedFilters ) : void { + $method = __METHOD__; + $dbw->onTransactionPreCommitOrIdle( + function () use ( $dbw, $loggedFilters, $method ) { + $dbw->update( 'abuse_filter', + [ 'af_hit_count=af_hit_count+1' ], + [ 'af_id' => $loggedFilters ], + $method + ); + }, + $method + ); + } +} diff --git a/includes/Watcher/Watcher.php b/includes/Watcher/Watcher.php index 49d7125c2..92d6c0abd 100644 --- a/includes/Watcher/Watcher.php +++ b/includes/Watcher/Watcher.php @@ -7,8 +7,9 @@ namespace MediaWiki\Extension\AbuseFilter\Watcher; */ interface Watcher { /** - * @param int[] $filters The filters that matched the action + * @param int[] $localFilters The local filters that matched the action + * @param int[] $globalFilters The global filters that matched the action * @param string $group */ - public function run( array $filters, string $group ) : void; + public function run( array $localFilters, array $globalFilters, string $group ) : void; }