* Affected components: MediaWiki deployment at WMF. And maybe Scap and/or MediaWiki core.
* Engineer for initial implementation: WMF Performance Team, WMF Service Ops
* Code steward: Performance Team.
Improve performance with lower backend latencies, by having PHP do less work on every web request.
The PHP version 7.4 provides a new way to tune performance in how the PHP code of an application is loaded and especially how caching of code of the application works. It introduces a way to preload PHP files that would otherwise be loaded on-demand when responding to web requests.
This RFC is for adding support for this feature in WMF's deployment of MediaWiki.
The goal of this RfC is the following steps being implemented in MediaWiki:
* Provide an entry point that can be referenced in the `opcache.preload` PHP ini setting, which will preload (some) of MediaWiki.
* Make it possible to preload significant parts of MediaWiki core and MediaWiki extensions source code.
##### Status quo
MediaWiki already greatly supports the use of many layers of caching, such as OpCache on the application code level, memcached and redis on the data level and so on. All of these layers are out of scope of this RfC. MediaWiki, as any other PHP application, still has the problem as described in the original [[ https://wiki.php.net/rfc/preload | php.net RfC ]] for the preloading feature.
However, to support the solution of the PHP RfC, each administrator of a PHP server needs to add an option to their php.ini with a path to a file which specifies the files that should be pre-loaded. This requires them to know what this list is. Exactly at this point, this RfC is pointing at.
There're some drawbacks from preloading an application or just parts of it into the php process:
* Changes to the file system of pre-loaded files will not be reflected in the php-process memory, hence making the file system changes not being reflected when requesting the application. This makes updating MediaWiki or parts of it more difficult as a server restart is required.
* Only one preload file can be specified, making different applications or versions of MediaWiki, running in the same php server, nearly impossible
* When class names are conflicting when pre-loading them, opt's them out from being cached, making preloading only reasonable for one application, only
* The implementation of this RfC needs to take into account, that code comes from MediaWiki core, as well as from extensions and also from composer and maybe other ways
* when pre-loading all, MediaWiki core, extensions and composer:
** Restarting php-fpm with preloading enabled may take a considerable longer time when all MediaWiki core, extensions and composer code is being preloaded
** The default shared memory and max memory limit values may not be high enough to load all code
There're many possible ways of how the preloading feature could be supported inside of MediaWiki.
##### Maintenance script (static preload file)
Using a maintenance script to generate the preload file (similar to how the autoload.php is updated in MediaWiki core) would allow a system administrator to run it right before deploying the MediaWiki installation to the production system. This allows the implementation to know exactly what files are present on the file system and therefore would just need to go over all the files in the MediaWiki installation and load them all into the cache.
##### Dynamic preload file
It seems it's possible to use a PHP class or function inside of the preload script, which then could go through the MediaWiki installation directory during the startup phase of the PHP server and provide all of the current files on the file system to the cache.
Composer has, as of December 2019, an [[ https://github.com/composer/composer/issues/7777 | outstanding issue ]] where possible ways of autoloading code of dependencies. As long as the issue is not solved, or if it does not provide a compatible way, MediaWiki core would simply include the files from composer and third-party dependencies in one of the solutions above.
### Other resources
* Symfony already [[ https://github.com/symfony/symfony/issues/29105 | added support ]] for preloading by generating a preload file into the cache folder of the framework
* Composer [[ https://github.com/composer/composer/issues/7777 | is discussing ]] about good ways how to support preloading