diff options
author | C. Scott Ananian <cscott@cscott.net> | 2024-10-30 15:39:10 -0400 |
---|---|---|
committer | C. Scott Ananian <cscott@cscott.net> | 2025-01-29 21:47:52 +0000 |
commit | df41aa3da19e5f817d1c05b7488fbe1122f7cde9 (patch) | |
tree | 16229691b802e6c9ccea7cee05c52d7ff30971a2 /tests/phpunit/includes/parser | |
parent | 03db3c6abf26129bfb0ee379e6789224338f8bf0 (diff) | |
download | mediawikicore-df41aa3da19e5f817d1c05b7488fbe1122f7cde9.tar.gz mediawikicore-df41aa3da19e5f817d1c05b7488fbe1122f7cde9.zip |
Add ParserOutputFlags::{HAS_ASYNC_CONTENT,ASYNC_NOT_READY}
This allows Parsoid to mark parses which contain async content which
is "not ready yet". At the moment this output is cached with a reduced
TTL, although in the future it might still be treated as uncacheable,
cached until evicted, or some other option.
The HAS_ASYNC_CONTENT flag along with ParserOutput::hasReducedExpiry()
ensures that RefreshLinksJob is opportunistically reinvoked whenever
the page is reparsed, since the asynchronous content may change the
metadata for the page when it becomes ready.
As describe in T373256, ::hasReducedExpiry() is misnamed now, and a
follow-up patch will probably rename it to ::hasDynamicContent() or
something like that. What it really means is "RefreshLinksJob must
be re-run on every parse, because the content may change on each
parse". In the past we would *also* reduce the cache time for
pages like this. But for asynchronous content, "the content may
change on each parse" only *until* the asynchronous content is
"ready". Once it is ready the contents will no longer change, and
the cache lifetime can be raised again -- but ::hasDynamicContent()
still needs to be set, which in the future will mean "you need to
check that RefreshLinksJob has last run" not "you must always run
RefreshLinksJob".
Asynchronous content will always set HAS_ASYNC_CONTENT, even after
the content is "ready", but will only set ASYNC_NOT_READY if it
needed to use placeholder content in this render.
Bug: T373256
Change-Id: I71e10f8a9133c16ebd9120c23c965b9ff20dabd2
Diffstat (limited to 'tests/phpunit/includes/parser')
-rw-r--r-- | tests/phpunit/includes/parser/ParserCacheSerializationTestCases.php | 2 | ||||
-rw-r--r-- | tests/phpunit/includes/parser/ParserOutputTest.php | 40 |
2 files changed, 42 insertions, 0 deletions
diff --git a/tests/phpunit/includes/parser/ParserCacheSerializationTestCases.php b/tests/phpunit/includes/parser/ParserCacheSerializationTestCases.php index 81674bc1c42e..db2b154e4cdc 100644 --- a/tests/phpunit/includes/parser/ParserCacheSerializationTestCases.php +++ b/tests/phpunit/includes/parser/ParserCacheSerializationTestCases.php @@ -46,6 +46,8 @@ abstract class ParserCacheSerializationTestCases { public const FAKE_CACHE_EXPIRY = 42; + public const FAKE_ASYNC_CACHE_EXPIRY = 3; + private const MOCK_EXT_DATA = [ 'boolean' => true, 'null' => null, diff --git a/tests/phpunit/includes/parser/ParserOutputTest.php b/tests/phpunit/includes/parser/ParserOutputTest.php index 95cf1b96131f..56f6cdcddb35 100644 --- a/tests/phpunit/includes/parser/ParserOutputTest.php +++ b/tests/phpunit/includes/parser/ParserOutputTest.php @@ -39,6 +39,10 @@ class ParserOutputTest extends MediaWikiLangTestCase { MainConfigNames::ParserCacheExpireTime, ParserCacheSerializationTestCases::FAKE_CACHE_EXPIRY ); + $this->overrideConfigValue( + MainConfigNames::ParserCacheAsyncExpireTime, + ParserCacheSerializationTestCases::FAKE_ASYNC_CACHE_EXPIRY + ); } public static function getClassToTest(): string { @@ -1517,12 +1521,48 @@ EOF // But calling ::get assigns a cache time $po->getCacheTime(); $this->assertTrue( $po->hasCacheTime() ); + $this->assertTrue( $po->isCacheable() ); // Reset cache time $po->setCacheTime( "20240207202040" ); $this->assertSame( "20240207202040", $po->getCacheTime() ); } /** + * @covers \MediaWiki\Parser\ParserOutput::isCacheable() + * @covers \MediaWiki\Parser\ParserOutput::getCacheExpiry() + * @covers \MediaWiki\Parser\ParserOutput::hasReducedExpiry() + */ + public function testAsyncNotReady() { + $defaultExpiry = ParserCacheSerializationTestCases::FAKE_CACHE_EXPIRY; + $asyncExpiry = ParserCacheSerializationTestCases::FAKE_ASYNC_CACHE_EXPIRY; + // $asyncExpiry has to be smaller than the default for these tests to + // work properly. + $this->assertTrue( $asyncExpiry < $defaultExpiry ); + + $po = new ParserOutput(); + $po->getCacheTime(); // assign a cache time + $this->assertTrue( $po->isCacheable() ); + $this->assertFalse( $po->hasReducedExpiry() ); + + // hasReducedExpiry is set if there is/was any async content + $po->setOutputFlag( ParserOutputFlags::HAS_ASYNC_CONTENT ); + $this->assertTrue( $po->isCacheable() ); + $this->assertTrue( $po->hasReducedExpiry() ); + $this->assertTrue( $po->getCacheExpiry() === $defaultExpiry ); + + // Setting ASYNC_NOT_READY also shortens the cache expiry + $po->setOutputFlag( ParserOutputFlags::ASYNC_NOT_READY ); + $this->assertTrue( $po->isCacheable() ); + $this->assertTrue( $po->hasReducedExpiry() ); + $this->assertTrue( $po->getCacheExpiry() === $asyncExpiry ); + + $po->updateCacheExpiry( $defaultExpiry - 1 ); + $this->assertTrue( $po->isCacheable() ); + $this->assertTrue( $po->hasReducedExpiry() ); + $this->assertTrue( $po->getCacheExpiry() === $asyncExpiry ); + } + + /** * @covers \MediaWiki\Parser\ParserOutput::getRenderId() * @covers \MediaWiki\Parser\ParserOutput::setRenderId() */ |