Extension:MediaWikiFarm

The extension MediaWikiFarm creates farms of wikis with the following main features:
 * Multiversion: As a standard MediaWiki extension, it turns MediaWiki into a single-version farm; installed "in front of MediaWiki" it creates multiversion farms;
 * Hierarchical configuration: The configuration can be written either in YAML, PHP, or JSON, in a hierarchical manner: default value, default value for the wikis family, value for a single wiki;
 * Performance: Caching, caching, caching; there is one cache per file, caches are written as PHP arrays to benefit from OPcache extension; with this cache architecture, this extension adds a mean time of 239µs per request compared to a standard LocalSettings.php (on a personal computer; PHP7+OPcache; 145µs for wiki selection + 93µs for configuration).

Detailed features

 * MediaWiki farm: each wiki is identified by its host, with dedicated version, configuration, and data directories;
 * Multiversion farm: each wiki is one of the installed MediaWiki version, with extensions and skins selected for this version, and extensions and skins activated or not for this wiki;
 * Hierarchical configuration: each parameter can be specified at different scales: for every wiki in the farm, for a specific family, or for a single wiki;
 * Multi-files configuration: the configuration can be distributed accross files with different permissions, e.g. all passwords in a secret file, other parameters in a public file;
 * Configuration in YAML, JSON, or PHP: these three file formats are supported (YAML needs an external library);
 * Transparent from MediaWiki point of view: the configuration part is just a sophisticated LocalSettings.php and the initial bootstraping code is hiding itself as much as possible;
 * Caches: all configuration files and final configuration are cached as PHP arrays, interoperables accross PHP versions and cacheable in OPcache;
 * CLI compatible: a command-line script selects the right wiki just like in the Web version;
 * Multi-farms: multiple farms can be created, each one with its own configuration files, possibly shared accross farms to e.g. create pre-production wikis with slightly different configurations;
 * Syntax-error-proof: syntax errors in configuration files do not crash the farm, just silently ignored when cache is activated;
 * Delayed version switch: during version switch, the version does not change until the maintenance/update.php script is run;
 * Custom 404: it can be displayed a customised HTTP 404 page for missing wikis, written in PHP or HTML;
 * Whole range of MediaWiki versions: every MediaWiki version from 1.1 to 1.28 works in multiversion farm (small issue for 1.1 and 1.2 still pending);
 * Wide range of PHP versions: every PHP version from 5.2 to 7.1 works (YAML library requires 5.3.2 or 5.5.9, so YAML-to-PHP must be handled separately for old MediaWiki versions);
 * Documented: all functions are documented and a general documentation is available in a subdirectory;
 * Translated: the description on Special:Version is translatable on TranslateWiki although, well, it’s the only string in the user interface;
 * Unit-tested, well: about 100 tests (250 assertions) run in 10-15 seconds in recent MediaWiki versions with PHP 5.6 to 7.1, totalling 100% code coverage with strict coverage activated and global variables under watch.

Installation
There are two installation modes:
 * an almost classical installation in the  subdirectory, but limited to single-version MediaWiki farms;
 * a more complex and completely unusual installation for multiversion MediaWiki farms.

These instructions are only minimal; you should read the documentation available in the subdirectory  to understand the goals, the basic concepts, and prepare your naming scheme (the URLs) and directory organisations before you start installing it.

Quick installation

 * Download the MediaWikiFarm extension and copy the directory in the usual subdirectory ;
 * 1) Optionally run Composer in the subdirectory extension (to read YAML files);
 * 2) Create a directory where you want to put your configuration, e.g.  ;
 * 3) Create and configure the main configuration file , e.g. from the sample file;
 * 4) Move your existing LocalSettings.php in this configuration directory;
 * 5) Copy the placeholder LocalSettings.php provided by MediaWikiFarm in your MediaWiki directory.

Multiversion installation
C.f. documentation in the subdirectory

Documentation
An extensive documentation is available in the subdirectory  of the extension. Some basic instructions should be transferred here (installation, basic configuration).

Be aware it is non-trivial to set up a MediaWiki farm; this extension only improves the MediaWiki part, after that it remains farm-type configuration of: DNS, webserver, MySQL, HTTPS, domain names, external services (memcached, Parsoid, *oid…), this is the job of a configuration management tool (puppet, Chef, Ansible, Cfengine, etc.).

Testing
The extension has been tested with a multiversion installation with MediaWiki ranging from 1.1 to 1.28alpha, with PHP 5.2 (MediaWiki 1.1-1.12), PHP 5.6 (MediaWiki 1.13-1.21), PHP 7.0 (MediaWiki >= 1.22), and PHP 7.1RC1 (MediaWiki 1.28alpha), with nginx 1.6.2 with fastcgi module. One minor issue is still pending to run MW 1.1 and 1.2.

There is a unit test suite with about 100 tests (250 assertions). This can be run with the customised MediaWiki PHPUnit (see tests/phpunit/phpunit.php in MW directory). This specific test suite can be run separately with. It should run without error with strict coverage, with a total code coverage of 100%. Only raw scripts and some untestable methods are code-coverage-ignored (4 methods out of 38). Note there is a global function that PHPUnit doesn’t code-coverage, see.

MediaWiki deactivated backup of global variables, but it can be re-enabled in this test suite by modifying the object property in constructor of MediaWikiFarmTestCase (slightly slower); in this case, expectedly-modified global variables are declared at the beginning of the test and any other global variable modified reports the test as risky. If a test is really long, possibly PHPUnit computes the differences of values of global variables between the beginning and the end of the test (count 10 minutes for a heavily modified global state).

See also User:Seb35/MediaWiki Archaeology.

Development
Some ideas:
 * reduce the initial bootstraping from 3 files read (farms.yml.php, versions.yml.php, config-version.php) to 2 (metadata.php, config-version.php)
 * document how to check performance, to have some standard way to compute it, e.g. is some special PHP files
 * done, to be committed: the strategy of loading separetely the different natures of parameters (settings, arrays, wfLoadSkin, wfLoadExtension, require_once) is not as efficient as a raw LocalSettings.php -> create a LocalSettings.php
 * create a LocalSettings.php in cache directory: on the 239µs used by MWF compared to a classical LS.php, this will save 93µs
 * collect more errors and warnings
 * think about ways to display errors+warnings, either on-wiki, on a central wiki, or on-file
 * handle constants like CACHE_NONE
 * add tags for transversal selection of wikis: think about file format, how to store them: lists and/or dictionaries
 * research if it would be possible to handle Composer-installed extensions (see this discussion), better is only the "activation" feature, but more probably it would have to hook Composer to create isolated "autoloading parts for a given wiki" with ideally all other code (MW extensions and Composer libraries) laying in their respective directories
 * add phpcs.xml

Related extensions

 * Extension:Farmer
 * Extension:Simple Farm
 * Extension:WikiFarm
 * Extension:Configure
 * Extension:Shared codebase
 * Extension:CreateWiki