Page MenuHomePhabricator

ResourceLoader module version must only change when effective output would change
Closed, DuplicatePublic

Description

There are various factors causing modules to invalidate and change their version timestamp or hash. Which in turn invalidates many caching layers, such as minification cache, varnish cache, browser HTTP cache, and client-side localStorage cache.

Goal to measure success:

When upgrading MediaWiki from one wmf-branch to the next, modules shouldn't invalidate their cache. Only if the module content changed (e.g. scripts, styles and other included resources).

Known problems are listed below.

  • File modules use timestamps that don't persist. With the way Wikimedia deploys MediaWiki right now, each upgrade involves a fresh clone with Git. As such, while Git only changes timestamps on-disk when files changed between checkouts, a new clone will always have the current timestamp for each file created during the clone.
  • Modules with messages use localisation cache timestamp. This one can be observed best on a local wiki with caching disabled. Modules with messages have a different version every time the startup module is generated.
  • File modules include absolute paths in their definition summary. (e.g. localBasePath, which is $IP, which at Wikimedia is a directory that includes a MediaWiki branch names like 1.26wmf4).
  • Undo/redo results in different versions. Users that skipped the intermittent state needlessly re-fetch resources.

Related Objects

Event Timeline

Krinkle created this task.May 4 2015, 10:50 PM
Krinkle raised the priority of this task from to Needs Triage.
Krinkle updated the task description. (Show Details)
Krinkle added a subscriber: Krinkle.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptMay 4 2015, 10:50 PM
Krinkle set Security to None.
Krinkle added a subscriber: ori.
Krinkle moved this task from Tag to Next-up on the Performance Issue board.May 18 2015, 5:52 PM
Krinkle renamed this task from Allow ResourceLoader caches to persist between MediaWiki wmf versions (tracking) to ResourceLoader module version must only change when effective output would change.Jun 4 2015, 8:10 PM
Krinkle updated the task description. (Show Details)
Krinkle removed a project: Tracking-Neverending.

Change 215857 had a related patch set uploaded (by Krinkle):
resourceloader: Replace ResourceLoaderWikiModule mtime queries with content hash

https://gerrit.wikimedia.org/r/215857

Change 210942 had a related patch set uploaded (by Krinkle):
resourceloader: Move packaging to a new getModuleContent() method

https://gerrit.wikimedia.org/r/210942

Change 215364 had a related patch set uploaded (by Krinkle):
resourceloader: Enable module content version for data modules

https://gerrit.wikimedia.org/r/215364

Krinkle updated the task description. (Show Details)Jun 4 2015, 8:19 PM

Change 215857 merged by jenkins-bot:
resourceloader: Refactor ResourceLoaderWikiModule to reduce database queries

https://gerrit.wikimedia.org/r/215857

Krinkle claimed this task.Jun 8 2015, 4:38 PM
Krinkle triaged this task as Normal priority.
Krinkle moved this task from Next-up to Doing on the Performance Issue board.
Krinkle removed a subscriber: gerritbot.

Change 210942 merged by jenkins-bot:
resourceloader: Move packaging to a new getModuleContent() method

https://gerrit.wikimedia.org/r/210942

Krinkle updated the task description. (Show Details)Jun 16 2015, 3:32 AM
Krinkle moved this task from Inbox to Doing on the Performance-Team board.

I experimented with enabling module content versioning for all modules (except WikiModule, which can't retrieve content, not significant right now).

Locally with latest master, a handful of common extensions installed, warm localisation cache, and mainCache=anything (db). Using $ time curl -i ...load.php?modules=startup&only=scripts&debug=false and XhprofProfiler (StartProfiler: $wgProfiler, ProfilerXhprof, ProfilerOutputDb; view via w/profileinfo.php). Truncate mw.profiling table before the http request.

Before any change, real time is about 1.4s. Sorting profiling data by time%, from 65% and up:

NameTime (%)CountCalls/reqms/callkb/callms/req
main()100%11346.140346.14
ResourceLoader::respond85.23%11295.020295.02
ResourceLoaderModule::getVersionHash [+]73.89%2662660.960255.76
ResourceLoader::{array_ma closure} [+]69.89%4460.480241.91
ResourceLoader::getCombinedVersion [+]69.87%22120.930241.86
ResourceLoaderStartUpModule::getDefinitionSummary68.75%11237.970237.97
ResourceLoaderStartUpModule::getAllModuleHashes65.49%11226.680226.68
..
ResourceLoaderFileModule::getDefinitionSummary9.19%2332330.18042.3
ResourceLoaderFileModule::getFileMtimes7.16%2332330.14032.92
ResourceLoaderModule::safeFilemtime3.72%5875870.03017.12
DatabaseBase::select [+]4.74%25250.87021.79
DatabaseBase::query [+]3.54%26260.63016.31
MessageBlobStore::get [+]2.1%10100.9709.68
ResourceLoader::makeHash0.55%2692690.0102.54

After setting enableModuleContentVersion to true in ResourceLoaderModule and ResourceLoaderFileModule the real time from up from 1.4s to 8.5s.

NameTime (%)CountCalls/reqms/callkb/callms/req
main()100%113226.5803226.58
ResourceLoader::respond98.29%113171.5203171.52
ResourceLoaderModule::getModuleContent [+]97.82%221578.1203156.25
ResourceLoaderModule::buildContent [+]97.82%221578.103156.19
ResourceLoaderStartUpModule::getScript97.72%221576.4703152.94
ResourceLoaderStartUpModule::getModuleRegistrations96.79%113123.0203123.02
ResourceLoaderModule::getVersionHash95.41%26626611.5703078.59
ResourceLoaderFileModule::getStyles67.32%2362369.202172.01
..
ResourceLoaderFileModule::compileLessFile55.35%303059.5301785.8
lessc::compile [+]55.02%303059.1701775.24
DatabaseBase::select [+]12.6%6326320.640406.59
DatabaseBase::query [+]9.68%6326320.490312.39
MessageBlobStore::get [+]7.72%2622620.950249.08
ResourceLoaderFileModule::getScript [+]5.11%2362360.710167.19
ResourceLoaderFileModule::readScriptFiles4.82%2362360.670157.61

Main hot spots are less compilation (60%), MessageBlobStore (10%), and script/style file reading (20%).

MessageBlobStore still queries about the same number of rows, but is now fetching the blob field (to then sha1) instead of timestamp field. The preloader is currently not populating that so hence the bump there. I imagine without MessageBlobStore it would be much worse (as this store currently saves thousands of memcached and cdb queries, per T90001). Making the preload query include the blobs should help keep the DatabaseBase::select count around 25 instead of going up to 630.

Closing in favour of T102578 (tracking the general issue) and T104950 (for FileModule).