Hypothesis WE5.2.3: If we conduct an experiment to reimplement at least [1-3] existing Core and Extension features using a new Domain Event and Listener platform component pattern as an alternative to traditional hooks, we will be able to confirm our assumption of this intervention enabling simpler implementation with more consistent feature behavior.
The goal of the Event Listeners exploration is to define events that are emitted by MediaWiki core, which can later be handled by listeners in other components of core, in extensions, or by logic running in a stand-alone service. Following the idea of domain events as defined in domain driven design, these events represent changes to the observable state maintained by a given component (or bounded context). This matches the behavior that had evolved organically for the hooks that we classified as “events” in the survey. We expect the application of the listener pattern to have the following benefits for the MediaWiki platform:
- Improve component boundaries between core components by applying the listener pattern. Listeners remove the need for the code that affects a change to know about all code that needs to be informed about it.
- Clarify the semantics of the notification received by the extension, particularly with respect to transactional context.
- Make the extension interface more future proof by avoiding the rigidity imposed by using PHP interfaces to define hook parameters. Due to limitations of PHP, method signatures defined by extensions can’t be modified in a backwards-compatible way.
- Make it easier to publish state changes on an event bus (Kafka) by implementing a generic relay mechanism.
To introduce the listeners into MediaWiki core we will define interfaces for emitting events and for registering listeners. We will implement a mechanism for dispatching events to the relevant listeners if and when the change in state has been successfully committed to the storage layer.
The proposed system can be implemented as a self-contained system, built on top of existing infrastructure such as HookContainer, DeferredUpdates, and EventRelayer in a straightforward way. It will be backwards compatible so existing extensions remain functional without any change, and implemented in such a way that allows us flexibility to change the implementation later, without affecting listeners. This allows us to first use the new system on a small selection of extensions and core components, and to adjust the interfaces and implementation as we expand usage.
Introducing the new system and testing it on just one of the 13 event hooks and a single extension is expected to take a small team of engineers one quarter. We intend to start with an event that represents page updates, because this would benefit a variety of different use cases both in core and in extensions.
Replacing all relevant hooks and converting more extensions will take longer. To avoid maintaining multiple competing systems for the same purpose for an extended period of time, a concerted effort should be made to migrate the majority of extensions by the end of the fiscal year. Migration should be straightforward and generally lead to a reduction in boilerplate code.
See also: