logger = $logger; $this->previousParseStackTraces = []; } /** * @param PageReference $page * @param int|null $revId * @param ParserOptions $options * @param ParserOutput $output */ public function notifyParse( PageReference $page, ?int $revId, ParserOptions $options, ParserOutput $output ) { $pageKey = CacheKeyHelper::getKeyForPage( $page ); $optionsHash = $options->optionsHash( $output->getUsedOptions(), Title::castFromPageReference( $page ) ); $index = $this->getParseId( $pageKey, $revId, $optionsHash ); $stackTrace = ( new RuntimeException() )->getTraceAsString(); if ( array_key_exists( $index, $this->previousParseStackTraces ) ) { // NOTE: there may be legitimate changes to re-parse the same WikiText content, // e.g. if predicted revision ID for the REVISIONID magic word mismatched. // But that should be rare. $this->logger->debug( __METHOD__ . ': Possibly redundant parse!', [ 'page' => $pageKey, 'rev' => $revId, 'options-hash' => $optionsHash, 'trace' => $stackTrace, 'previous-trace' => $this->previousParseStackTraces[$index], ] ); } $this->previousParseStackTraces[$index] = $stackTrace; } /** * @param string $titleStr * @param int|null $revId * @param string $optionsHash * @return string */ private function getParseId( string $titleStr, ?int $revId, string $optionsHash ): string { // $revId may be null when previewing a new page $revIdStr = $revId ?? ""; return "$titleStr.$revIdStr.$optionsHash"; } }