There are a handful of areas in MediaWiki core that we've historically treated as a vertical. This stems from a time where WMF was smaller, and MediaWiki was largely maintained as a single unit. In that time, the notion of a dedicated teams owning a only specific feature within core was the exception rather than the rule, so we've always handled it without much structure, folding it into the larger hole.
Motivation
Especially for Gerrit queries, this proposal should not only reduce duplicate effort but also makes commits affecting a component more likely to be discoverable in the first place, thus reduce code review latency and increase inter-team awareness of relevant changes, as people are currently unlikely to bother listing out each of these files, not to mention when files are moved or renamed, or when new files are added.
Typically, it goes as follows:
- The main business logic of a feature goes in /includes/something. Nowadays this includes e.g. relevant interfaces, value objects, and service classes.
- If the feature uses the JobQueue, we defined a SomethingJob in /includes/jobqueue/jobs/, which is generally small and simply calls the Something service class.
- If the feature uses DeferredUpdates, we place its classes in /includes/defered/, which are generally small and call the Something service class.
- If the feature has a user-facing API, we define ApiSomething (ApiBase subclass) to /includes/api/, which likewise calls the Something service.
- If the feature has a user-facing GUI, we define SpecialSomething in includes/specials/.
- If the feature stores its own data, we define tables within /maintenance/tables.json.
There may also be sysadmin-facing maintenance script in /maintenance/, and/or frontend resources under /resources/src/mediawiki.something/.
Impact
For most core components, you typically have only 2 or 3 of the above. Yet, this is enough to end up duplicating a fair bit of information in many different places, which are typically not in sync, or simply missing all but the first entry.
- Automate and improve reporting of production errors and other Phabricator tasks.
- e.g. when reporting production errors in Phabricator, the stack traces will now clearly identify the relevant component, without needing to remember or check what an individual class does.
- Remove need to hardcode out-of-component files in various places, such as:
- component descriptions on the mediawiki.org Maintainers page at https://www.mediawiki.org/wiki/Maintainers.
- User preferences: The preferences system, including the PreferencesFactory and UserOptionsManager services, their interface (Special/API), and database table.
- component descriptions on Phabricator, for example:
- MediaWiki-Recent-changes The recent changes feature in MediaWiki core. Including Special:RecentChanges/Special:NewPages, the recentchanges API module, and the recentchanges database table.
- MediaWiki-Blocks Blocking and unblocking users, including the Block API, Special page, and database table. Also includes the interfaces for listing blocks (e.g. Special:AutoblockList).
- component descriptions on the mediawiki.org Maintainers page at https://www.mediawiki.org/wiki/Maintainers.
- Automate and improve code review discovery:
- Gerrit query for "commits" on the Maintainers page at https://www.mediawiki.org/wiki/Maintainers.
- Gerrit query for configuration of reviewer bot at https://www.mediawiki.org/wiki/Git/Reviewers.
- Gerrit query for team dashboards such as https://gerrit.wikimedia.org/r/p/wikimedia/+/dashboard/teams:platform
- Gerrit query for watching code in Gerrit preferences at https://gerrit.wikimedia.org/r/settings/#Notifications.
Scope
As part of this specific task, I propose we handle these two areas only. This keeps the task focussed and scoped to consensus on the direction rather than specific details, which for other areas can be handled in separate tasks, after the direction is agreed upon. It may also be spread out over a larger period of time, with separate goals for separate areas. In particular, I want to avoid a rushed conclusion where many more times amounts of hidden work are required afterwards where the "real" decisions are made.
- JobQueue jobs from /includes/jobqueue/jobs/
- Deferred updates from /includes/deferred/
We can start with deferred updates. For deferred updates, there are a few internal classes (that contain no business logic!) that exist to be extended by specific deferred updates, such as AtomicSectionUpdate. These are part of the DeferredUpdates system and the API this system provides to extensions. These will not move. What we move are the edges that implement specific features, e.g. SearchUpdate would move to /includes/search/, and MessageCacheUpdate to /includes/language/.
We can then repeat this for jobs where there is clearly 1 component a class belongs to, and where that component has its own well-named directory. For the handful that are left, we can investigate what is needed for there to be a clear component (e.g. a minor edit to a description or non-PSR directory name may be required to recognise if a directory's scope has changed over the past decade). Note that NullJob and DuplicateJob are internal classes leverared by the JobQueue system itself, and would not move.
Misc notes
In-take for tasks in a sustainable way, encourage components and teams, not broad categories. This motivated these changes:
- Re-scope MediaWiki-Database to MediaWiki-libs-Rdbms, then own+triage. Details at T228360: Narrow scope of MediaWiki-Database workboard.
- Re-scope MediaWiki-Cache to MediaWiki-libs-BagOStuff, then own+triage.
- Re-scope MediaWiki-Hook to only the system, MediaWiki-Core-Hooks.
- Re-scope MediaWiki-SpecialPages to only the system, MediaWiki-Special-pages, details in tag description (unfinished).
- Decline T268386: Create #mediawiki-actions component, details at T268386#6654517.
- Full list at MediaWiki-General