Revert "Move NewPP limit report HTML comments to JS variables" and followups
[lhc/web/wiklou.git] / includes / parser / ParserOutput.php
index f052812..d2ef5e3 100644 (file)
@@ -188,7 +188,9 @@ class ParserOutput extends CacheTime {
         */
        private $mExtensionData = [];
 
-       /** @var array $mLimitReportData Parser limit report data. */
+       /**
+        * @var array $mLimitReportData Parser limit report data.
+        */
        private $mLimitReportData = [];
 
        /**
@@ -209,9 +211,21 @@ class ParserOutput extends CacheTime {
        /** @var integer|null Assumed rev ID for {{REVISIONID}} if no revision is set */
        private $mSpeculativeRevId;
 
+       /** @var integer Upper bound of expiry based on parse duration */
+       private $mMaxAdaptiveExpiry = INF;
+
        const EDITSECTION_REGEX =
                '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#';
 
+       // finalizeAdaptiveCacheExpiry() uses TTL = MAX( m * PARSE_TIME + b, MIN_AR_TTL)
+       // Current values imply that m=3933.333333 and b=-333.333333
+       // See https://www.nngroup.com/articles/website-response-times/
+       const PARSE_FAST_SEC = .100; // perceived "fast" page parse
+       const PARSE_SLOW_SEC = 1.0; // perceived "slow" page parse
+       const FAST_AR_TTL = 60; // adaptive TTL for "fast" pages
+       const SLOW_AR_TTL = 3600; // adaptive TTL for "slow" pages
+       const MIN_AR_TTL = 15; // min adaptive TTL (for sanity, pool counter, and edit stashing)
+
        public function __construct( $text = '', $languageLinks = [], $categoryLinks = [],
                $unused = false, $titletext = ''
        ) {
@@ -979,34 +993,24 @@ class ParserOutput extends CacheTime {
        /**
         * Sets parser limit report data for a key
         *
-        * If $value consist of a list of two floats, it will be interpreted as
-        * (actual value, maximum allowed value). The presence of a "-" in $key will cause
-        * the first part of the key to be interpreted as a namespace.
+        * The key is used as the prefix for various messages used for formatting:
+        *  - $key: The label for the field in the limit report
+        *  - $key-value-text: Message used to format the value in the "NewPP limit
+        *      report" HTML comment. If missing, uses $key-format.
+        *  - $key-value-html: Message used to format the value in the preview
+        *      limit report table. If missing, uses $key-format.
+        *  - $key-value: Message used to format the value. If missing, uses "$1".
+        *
+        * Note that all values are interpreted as wikitext, and so should be
+        * encoded with htmlspecialchars() as necessary, but should avoid complex
+        * HTML for sanity of display in the "NewPP limit report" comment.
         *
         * @since 1.22
-        * @param string $key Data key
-        * @param mixed $value Data value One of (float, string, bool, JSON serializable array)
+        * @param string $key Message key
+        * @param mixed $value Appropriate for Message::params()
         */
        public function setLimitReportData( $key, $value ) {
-               if ( is_array( $value ) ) {
-                       if ( array_keys( $value ) === [ 0, 1 ]
-                               && is_numeric( $value[0] )
-                               && is_numeric( $value[1] )
-                       ) {
-                               $data = [ 'value' => $value[0], 'limit' => $value[1] ];
-                       } else {
-                               $data = $value;
-                       }
-               } else {
-                       $data = $value;
-               }
-
-               if ( strpos( $key, '-' ) ) {
-                       list( $ns, $name ) = explode( '-', $key, 2 );
-                       $this->mLimitReportData[$ns][$name] = $data;
-               } else {
-                       $this->mLimitReportData[$key] = $data;
-               }
+               $this->mLimitReportData[$key] = $value;
        }
 
        /**
@@ -1037,9 +1041,41 @@ class ParserOutput extends CacheTime {
        }
 
        /**
-        * Save space for serialization by removing useless values
-        * @return array
+        * Lower the runtime adaptive TTL to at most this value
+        *
+        * @param integer $ttl
+        * @since 1.28
         */
+       public function updateRuntimeAdaptiveExpiry( $ttl ) {
+               $this->mMaxAdaptiveExpiry = min( $ttl, $this->mMaxAdaptiveExpiry );
+               $this->updateCacheExpiry( $ttl );
+       }
+
+       /**
+        * Call this when parsing is done to lower the TTL based on low parse times
+        *
+        * @since 1.28
+        */
+       public function finalizeAdaptiveCacheExpiry() {
+               if ( is_infinite( $this->mMaxAdaptiveExpiry ) ) {
+                       return; // not set
+               }
+
+               $runtime = $this->getTimeSinceStart( 'wall' );
+               if ( is_float( $runtime ) ) {
+                       $slope = ( self::SLOW_AR_TTL - self::FAST_AR_TTL )
+                               / ( self::PARSE_SLOW_SEC - self::PARSE_FAST_SEC );
+                       // SLOW_AR_TTL = PARSE_SLOW_SEC * $slope + $point
+                       $point = self::SLOW_AR_TTL - self::PARSE_SLOW_SEC * $slope;
+
+                       $adaptiveTTL = min(
+                               max( $slope * $runtime + $point, self::MIN_AR_TTL ),
+                               $this->mMaxAdaptiveExpiry
+                       );
+                       $this->updateCacheExpiry( $adaptiveTTL );
+               }
+       }
+
        public function __sleep() {
                return array_diff(
                        array_keys( get_object_vars( $this ) ),