[MediaWiki-commits] [Gerrit] mediawiki...PageViewInfo[master]: Add cache layer to the service
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/320325 ) Change subject: Add cache layer to the service .. Add cache layer to the service Change-Id: Ib8feb757caf1f19c0b245fd90aec42537b0a84a7 --- M extension.json M i18n/en.json M i18n/qqq.json A includes/CachedPageViewService.php M includes/Hooks.php M includes/ServiceWiring.php A tests/phpunit/CachedPageViewServiceTest.php 7 files changed, 654 insertions(+), 37 deletions(-) Approvals: jenkins-bot: Verified Anomie: Looks good to me, approved diff --git a/extension.json b/extension.json index 8a24ff3..923ef1c 100644 --- a/extension.json +++ b/extension.json @@ -14,6 +14,7 @@ "AutoloadClasses": { "MediaWiki\\Extensions\\PageViewInfo\\Hooks": "includes/Hooks.php", "MediaWiki\\Extensions\\PageViewInfo\\PageViewService": "includes/PageViewService.php", + "MediaWiki\\Extensions\\PageViewInfo\\CachedPageViewService": "includes/CachedPageViewService.php", "MediaWiki\\Extensions\\PageViewInfo\\WikimediaPageViewService": "includes/WikimediaPageViewService.php" }, "MessagesDirs": { diff --git a/i18n/en.json b/i18n/en.json index 339d0b0..02f836c 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -8,5 +8,7 @@ "pvi-month-count": "Page views in the past 30 days", "pvi-close": "Close", "pvi-range": "$1 - $2", - "pvi-invalidresponse": "Invalid response" + "pvi-invalidresponse": "Invalid response", + "pvi-cached-error": "An earlier attempt to fetch this data failed. To limit server load, retries have been blocked for $1.", + "pvi-cached-error-title": "An earlier attempt to fetch page \"$1\" failed. To limit server load, retries have been blocked for $2." } diff --git a/i18n/qqq.json b/i18n/qqq.json index ba260de..6a186c0 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -9,5 +9,7 @@ "pvi-month-count": "Label for table cell containing page views in past 30 days", "pvi-close": "Text on button to close a dialog\n{{Identical|Close}}", "pvi-range": "Title of dialog, which is the date range the graph is for. $1 is the starting date, $2 is the ending date.", - "pvi-invalidresponse": "Error message when the REST API response data does not have the expected structure." + "pvi-invalidresponse": "Error message when the REST API response data does not have the expected structure.", + "pvi-cached-error": "Shown when the cached result is an error. $1 is the retry delay in human-readable form (e.g. \"30 minutes\").", + "pvi-cached-error-title": "Shown when the cached result (which is part of a larger resultset) is an error. $1 is the page name, $2 the retry delay in human-readable form (e.g. \"30 minutes\")." } diff --git a/includes/CachedPageViewService.php b/includes/CachedPageViewService.php new file mode 100644 index 000..b3fb540 --- /dev/null +++ b/includes/CachedPageViewService.php @@ -0,0 +1,240 @@ +service = $service; + $this->logger = new NullLogger(); + $this->cache = $cache; + $this->prefix = $prefix; + } + + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + } + + /** +* Set the number of days that will be cached. To avoid cache fragmentation, the inner service +* is always called with this number of days; if necessary, the response will be expanded with +* nulls. +* @param int $cachedDays +*/ + public function setCachedDays( $cachedDays ) { + $this->cachedDays = $cachedDays; + } + + public function supports( $metric, $scope ) { + return $this->service->supports( $metric, $scope ); + } + + public function getPageData( array $titles, $days, $metric = self::METRIC_VIEW ) { + $status = $this->getTitlesWithCache( $metric, $titles ); + $data = $status->getValue(); + foreach ( $data as $title => $titleData ) { + if ( $days < $this->cachedDays ) { + $data[$title] = array_slice( $titleData, -$days, null, true ); + } elseif ( $days > $this->cachedDays ) { + $data[$title] = $this->extendDateRange( $titleData, $days ); + } + } + $status->setResult( $status->isOK(), $data ); + return $status; + } + + public function getSiteData( $days, $metric = self::METRIC_VIEW ) { + $status = $this->getWithCache( $metric, self::SCOPE_SITE ); + if ( $status->isOK() ) { + $data = $status->getValue(); + if ( $days < $this->cachedDays ) { + $data = array_slice(
[MediaWiki-commits] [Gerrit] mediawiki...PageViewInfo[master]: Add cache layer to the service
Gergő Tisza has uploaded a new change for review. https://gerrit.wikimedia.org/r/320325 Change subject: Add cache layer to the service .. Add cache layer to the service Change-Id: Ib8feb757caf1f19c0b245fd90aec42537b0a84a7 --- M extension.json M i18n/en.json M i18n/qqq.json A includes/CachedPageViewService.php M includes/Hooks.php M includes/ServiceWiring.php A tests/phpunit/CachedPageViewServiceTest.php 7 files changed, 654 insertions(+), 37 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/PageViewInfo refs/changes/25/320325/1 diff --git a/extension.json b/extension.json index 8a24ff3..923ef1c 100644 --- a/extension.json +++ b/extension.json @@ -14,6 +14,7 @@ "AutoloadClasses": { "MediaWiki\\Extensions\\PageViewInfo\\Hooks": "includes/Hooks.php", "MediaWiki\\Extensions\\PageViewInfo\\PageViewService": "includes/PageViewService.php", + "MediaWiki\\Extensions\\PageViewInfo\\CachedPageViewService": "includes/CachedPageViewService.php", "MediaWiki\\Extensions\\PageViewInfo\\WikimediaPageViewService": "includes/WikimediaPageViewService.php" }, "MessagesDirs": { diff --git a/i18n/en.json b/i18n/en.json index 339d0b0..02f836c 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -8,5 +8,7 @@ "pvi-month-count": "Page views in the past 30 days", "pvi-close": "Close", "pvi-range": "$1 - $2", - "pvi-invalidresponse": "Invalid response" + "pvi-invalidresponse": "Invalid response", + "pvi-cached-error": "An earlier attempt to fetch this data failed. To limit server load, retries have been blocked for $1.", + "pvi-cached-error-title": "An earlier attempt to fetch page \"$1\" failed. To limit server load, retries have been blocked for $2." } diff --git a/i18n/qqq.json b/i18n/qqq.json index ba260de..6a186c0 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -9,5 +9,7 @@ "pvi-month-count": "Label for table cell containing page views in past 30 days", "pvi-close": "Text on button to close a dialog\n{{Identical|Close}}", "pvi-range": "Title of dialog, which is the date range the graph is for. $1 is the starting date, $2 is the ending date.", - "pvi-invalidresponse": "Error message when the REST API response data does not have the expected structure." + "pvi-invalidresponse": "Error message when the REST API response data does not have the expected structure.", + "pvi-cached-error": "Shown when the cached result is an error. $1 is the retry delay in human-readable form (e.g. \"30 minutes\").", + "pvi-cached-error-title": "Shown when the cached result (which is part of a larger resultset) is an error. $1 is the page name, $2 the retry delay in human-readable form (e.g. \"30 minutes\")." } diff --git a/includes/CachedPageViewService.php b/includes/CachedPageViewService.php new file mode 100644 index 000..b3fb540 --- /dev/null +++ b/includes/CachedPageViewService.php @@ -0,0 +1,240 @@ +service = $service; + $this->logger = new NullLogger(); + $this->cache = $cache; + $this->prefix = $prefix; + } + + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + } + + /** +* Set the number of days that will be cached. To avoid cache fragmentation, the inner service +* is always called with this number of days; if necessary, the response will be expanded with +* nulls. +* @param int $cachedDays +*/ + public function setCachedDays( $cachedDays ) { + $this->cachedDays = $cachedDays; + } + + public function supports( $metric, $scope ) { + return $this->service->supports( $metric, $scope ); + } + + public function getPageData( array $titles, $days, $metric = self::METRIC_VIEW ) { + $status = $this->getTitlesWithCache( $metric, $titles ); + $data = $status->getValue(); + foreach ( $data as $title => $titleData ) { + if ( $days < $this->cachedDays ) { + $data[$title] = array_slice( $titleData, -$days, null, true ); + } elseif ( $days > $this->cachedDays ) { + $data[$title] = $this->extendDateRange( $titleData, $days ); + } + } + $status->setResult( $status->isOK(), $data ); + return $status; + } + + public function getSiteData( $days, $metric = self::METRIC_VIEW ) { + $status = $this->getWithCache( $metric, self::SCOPE_SITE ); + if ( $status->isOK() ) { + $data = $status->getValue(); + if ( $days < $this->cachedDays ) { +