0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 08:12:37 +01:00

modules: Update README blerb.

This commit is contained in:
Jason Volk 2019-05-03 15:38:29 -07:00
parent 1d0a7d700d
commit 35f29c411c

View file

@ -2,11 +2,12 @@
This directory contains dynamically loadable functionality to libircd. These
modules are not mere extensions -- they provide essential application
functionality, but are not required to be directly linked in libircd proper.
Most application-specific functionality (i.e "business logic") is contained
in modules within this tree. At the time of this writing, a significant amount
of matrix functionality is still contained within libircd proper, but it is
intended that as many definitions as possible are pushed out into modules.
functionality, but are not always required to be directly linked in libircd
proper. Most application-specific functionality (i.e "business logic") is
contained in modules within this tree. At the time of this writing, a
significant amount of matrix functionality is still contained within libircd
proper, but it is intended that as many definitions as possible are pushed out
into modules.
#### Layout
@ -29,6 +30,30 @@ this may be subject to improvement.
- `m_` modules implement protocol logic for matrix event types.
- `vm_` modules provide the processing logic for matrix events.
#### Approach
We use a hybrid system to build modules with two techniques:
- Self-contained shared objects loaded for explicit import and export
of their symbols. This is the classical module which is safely loaded, unloaded
and accessed at any time via the `ircd::mods::import` system. This approach is
preferred for the majority of module and extension cases. Definitions in these
modules are not declared in `include/ircd` unless a "thunk" definition inside
libircd contains am `ircd::mods::import` calling out to the module (this is not
generated; developer must place this).
- "core" modules which directly implement symbols declared in `include/ircd`
headers. When this type of module is not loaded those headers declare an
undefined symbol and accesses will immediately crash. This approach is used
when large interfaces are implemented by modules and individual imports
defined in libircd are too cumbersome. This involves global binding made
possible by the dynamic linker. This approach is satisfactory because of
C++ symbol namespacing and modern compiler and linker controls. These modules
*can* still be unloaded (and are during shutdown) but only after every other
module which has accessed its symbols has also been unloaded. At this time,
we have no access or control over that reference system and the reasons for
a failure to unload may not be immediately clear or easy to trace.
#### Loading
Modules may be automatically loaded based on their prefix. Certain prefixes
@ -41,13 +66,16 @@ module is not loaded.
#### Unloading
Unlike previous incarnations of IRCd, every module is "unloadable" and there are
no "core" modules. All central linkages within libircd (and direct links made
by other modules) tolerate the unavailability of a module by using weak-pointers
and throwing exceptions. Unlike the Atheme approach as well, linkage into a module
does not prevent unloading due to dependency; the unloading of a module is
propagated to linksites through the weak_ptr's dependency graph and exceptions are
thrown from the link upon next use.
Unlike previous incarnations of IRCd, every module is [eventually] "unloadable"
and the notion of a "core" module is modernized based on the dynamic linker
technology available.
Many central linkages within libircd (and direct links made by other modules)
are imports which tolerate the unavailability of a module by using weak-pointers
and throwing exceptions. Unlike the Atheme approach as well, importing from a
module does not prevent unloading due to dependency; the unloading of a module is
propagated to linksites through the weak_ptr's dependency graph and exceptions
are thrown from the link upon next use.
Furthermore, modules are free to leverage the ircd::ctx system to wait
synchronously for events which are essential for a clean load or unload, even
@ -55,11 +83,11 @@ during static initialization and destruction. This is a useful feature which
allows all modules to be robustly loadable and unloadable at **any time**
and **every time** in an intuitive manner.
No modules in this system "stick" whether by accident or on purpose upon
unload. Though we all know that dlclose() does not guarantee a module
is actually unloaded, we expend the extra effort to ensure there is no
reason why dlclose() would not unload the module. This static destruction of
a module is verified and alarms will go off if it is actually "stuck" and
No modules used through imports in this system "stick" whether by accident or
on purpose upon unload. Though we all know that dlclose() does not guarantee
a module is actually unloaded, we expend the extra effort to ensure there is
no reason why dlclose() would not unload the module. This static destruction
of a module is verified and alarms will go off if it is actually "stuck" and
the developer *must* fix this.
## Getting started
@ -73,7 +101,7 @@ Every loadable module requires a static `ircd::mapi::header` with the explicit
name of `IRCD_MODULE`. This is an object which will be sought by the module
loader in libircd. Nothing else is required.
#### Approach
#### Developer's Approach
The ideal module in this system is one that is self-contained in that its only
interface is through "registrations" to various facilities provided by libircd.