Extension:MediaWikiFarm/Internals

MediaWikiFarm modes
MediaWikiFarm has many different functioning modes. Ideally testing takes into account this variability to test the realistic execution paths.


 * MediaWikiFarm modes, by raw order of importance:
 * 1) Installation type: monoversion or multiversion
 * 2) Cache: no cache, empty cache, up-to-date cache, expired cache
 * 3) Known environment: yes or no
 * 4) Data source for the MW versions: 'variables' files, 'versions' file
 * 5) Delayed upgrade: 'deployments' file or not
 * 6) Entry point: update.php or not


 * Incidental MediaWiki characteristics:
 * 1) Extension registration: yes or no


 * Incidental MediaWiki extension characteristics:
 * 1) Loading mechanism: Composer-managed, extension registration available, require_once available, both mechanisms available


 * Notes:
 * The MW version for a specific wiki can be defined in various files, the diffent name are according to the key names in farms.yml
 * The known environment is the internal property MediaWikiFarm::environment: when MWF is started in multiversion mode it does not know at this time the whole environment to compile the whole configuration for the wiki, this is only fully known later; currently this environment is only if the selected MediaWiki version is supporting extension registration or not
 * The delayed upgrade is a mechanism to smooth the upgrade process (but it can be deactivated): first you change the MW version, which has no effect, then you run the script, which uses the newly-defined version, and at the end of this script, the new version becomes globally active; this is to avoid a state where MediaWiki runs but update.php has not been executed
 * The entry point is a minor mode, only the  maintenance script can set MWF in other execution path and only when the delayed upgrade is active

Configuration planes
A configuration parameter can be changed by different partly-intersecting planes:
 * 1) Scope of the configuration file, defined by the key and default key in  : the broader scope it is, the more different wikis can be impacted
 * The key can be fixed (scope=wiki or tag or suffix or all), or the key and default can contain a star (wildcard) to catch many wikis but with some restrictions (e.g. only a suffix)
 * 1) Priority inside a config file: the smaller the scope of the definition is, the higher the priority is
 * 0=default MW; 1=default value from general default config file; 2=other default value; 3=suffix scope; 4=tag scope; 5=wiki-specific
 * 1) Place in the list of configuration files defined in
 * 2) Diff array variable or not: in the first case, only the “diff” is changed (some keys are added); in the second, the whole variable is replaced (possibly it can be an array which is entirely replaced); this plane is completely independant of the others

Composer-installed extensions
3 possible strategies: Then, during MediaWiki execution, /vendor/autoload.php loads the required /vendor/composerKEY (possibly multiple such directories) and hence the requested extensions are loaded (possibly a class could be loaded by multiple autoloaders, it’s not grave, and it could be avoided as an improvement). Given the new tendency to autoload classes with Composer (e.g. PSR-4) then activate the extension with wfLoadExtension (PageForms, etc.), we could use the dependency graph obtained from composer.json to correctly sort the various wfLoadExtension functions. For implementation, it is probable possible to obtain the dependencies from Composer with a plugin installed in composer.json in mwcomposer.json.
 * 1) Bold: A script (mwcomposer.php) iterates overs Composer-installed extensions and skins (type: mediawiki-extension or mediawiki-skin), creates as much /vendor/composer directories as there are combinations (= 2^n = \sum_{k=0}^n C(n,k), where n = #extensions), each one with a key (e.g. a hash of its content), then replaces the /vendor/autoload.php by a customised file; this one get the Composer key from MediaWiki (for now when used in multiversion mode, since configuration can be loaded before in this mode) and require_once the right composer subdirectory.
 * 2) Conservative: Similar to the previous scenario, but creates as much MediaWiki directories as there are combinaisons (2^n)
 * 3) Quick bold: Like the bold strategy, but instead of iterating over all combinations, just iterating over extensions , create /vendor/composerKEY for each extensions (inside, it contains all other required extensions and libraries), and read in each composer.json the dependencies. The first step of the iteration remains with all extensions activated, so that Composer handles at the beginning if there are incompatible extensions and we are sure, after this step, there exists a coherent versions set.

Benefits/drawbacks:
 * 1) Bold:
 * 2) *  less disk space used, cleaner (not many MW installations)
 * 3) *  bold (more issues expected), the customised binary Composer must be used instead, O(n^2) complexity
 * 4) Conservative:
 * 5) *  fully compatible with MediaWiki and Composer, even old versions
 * 6) *  more disk space used, less practical to manage MediaWiki
 * 7) Quick bold:
 * 8) *  even less disk space used, cleaner (not many MW installations), O(n) complexity
 * 9) *  bold (more issues expected), the customised binary Composer must be used instead, it reads composer.json so more maintenance expected, possibly a bit slower at runtime than bold (a per-wiki cache could be created, it could be thought)