Skip to content

Lifecycles and Listeners

Chris edited this page Oct 23, 2018 · 1 revision

The lifecycle system in Manticore is a powerful concept that allows for separation of concerns in the code while allowing the flexibility for a module to pick which parts of Manticore to get data from as it runs. The index.js file inside the /api/../app folder is the entry point of all the complex logic, and yet it delegates most of its work to other modules. This delegation is handled by the concept of lifecycle events and a listener loading system.

Listeners

The listeners folder is a location where Manticore functionality can be freely extended without the worry of modifying existing code or possibly messing up other parts of the program. The listener folder has an array of modules, where each module is a named folder explaining what the module does, and an index.js file. This file exports an object where each property name corresponds to a lifecycle event. By adding these properties to the exports object the module will be able to listen in on those events when they happen, and Manticore will pass to them a context object containing whatever data is there at the time. There are many different types of lifecycle hooks, but the most notable ones are the websocket events (ws-connect, ws-message, ws-disconnect) and the KV store watch events (request, waiting-find, waiting-job-advance). All possible lifecycle events are specified in the loader.js file.

Listener Loader

The file /api/../app/loader.js is responsible for looking in the listeners folder and loading all the modules inside that folder for use. The loader file constructs a store of listeners, where all listeners of the same type will be loaded together in a middleware stack, very similar to how express/koa apps have middleware chains to deal with API requests. So, if Manticore triggers a lifecycle event, then all listeners that had that property set in their module will be invoked in some kind of order, and they will each be passed the same context object which contains specific data regarding that event. Each module reads that data, possibly modifies it, and passes along control to the next one via calling a next function.

Lifecycle Types

Note that the order is not controllable, and so issues will arise if any of the modules modify the context object and change the expected structure for future modules down the chain. That’s why there are two different lifecycle event types. One of them is a read-only lifecycle event. Their names are usually marked with a pre- or a post- prefix for clarity’s sake. Modules listening for these events are strongly discouraged to alter the context object data. The other type of lifecycle event permits reading and modifying the context object, and is called a main hook. In this case, only one listener module should subscribe to that event so that no unexpected data transformations on the context object can happen. Manticore will still allow multiple listeners to that event, but it has the ability to know when this happens and will warn you if you have more than one listener attached to a main hook. Check loader.js to see which events are main hooks and which are read-only hooks.