Plugin Manager
Manages plugin discovery, loading, configuration, lifecycle, and event dispatch.
This module is central to the plugin architecture of the Bedrock Server Manager.
The PluginManager class handles all aspects of plugin interaction, including:
Locating plugin files in designated directories.
Reading and writing plugin configurations (e.g., enabled status, metadata) from/to the application database.
Validating plugins (e.g., ensuring they subclass
PluginBaseand have aversionattribute).Dynamically loading valid and enabled plugins.
Managing the lifecycle of plugins (e.g., calling
on_load,on_unloadevent hooks).Dispatching application-wide events to all loaded plugins.
Facilitating custom inter-plugin event communication. Custom event names must follow a ‘namespace:event_name’ format (e.g.,
myplugin:data_updated).Providing a mechanism to reload all plugins.
- class bedrock_server_manager.plugins.plugin_manager.PluginManager(app_context: AppContext)
Bases:
objectManages the discovery, loading, configuration, and lifecycle of all plugins.
This class is the core of the plugin system. It scans for plugins, manages their configuration in the database, loads enabled plugins, and dispatches various events to them.
- load_plugins() None
Discovers, validates, and loads all enabled plugins.
This method orchestrates the entire plugin loading process:
Calls
_synchronize_config_with_disk()to ensure the plugin configuration (self.plugin_config) is up-to-date with files on disk and that all plugin entries are valid.Clears any previously loaded plugin instances from
self.plugins. This is important for supporting thereload()functionality.Iterates through the synchronized
self.plugin_config:If a plugin is marked as
enabledin its configuration and has a validversion:Finds the plugin’s file path using
_find_plugin_path().Loads the plugin class from the file using
_get_plugin_class_from_path().
- iii.If class loading is successful, instantiates the plugin class.
The instance is provided with its name, a
api_bridge.AppAPIinstance (for core interaction), and a dedicatedlogging.Loggerinstance.
Appends the new plugin instance to the
self.pluginslist.Dispatches the
on_loadevent to the newly loaded plugin instance viadispatch_event().
Errors during the loading or instantiation of individual plugins are logged, and the process continues with other plugins.
- async shutdown()
Gracefully unloads all plugins asynchronously to prevent blocking.
- unload_plugins()
Unloads all currently active plugins.
This method provides a way to refresh the plugin system without restarting the entire application. It involves:
Dispatching the
on_unloadevent to all currently loaded plugins (viadispatch_event()).Clearing all registered custom event listeners from
self._event_listeners(as the plugins that registered them are being unloaded).
- get_native_ui_routes() List[Dict[str, str]]
Collects routes from all plugin routers that are tagged for Native V2 UI rendering.
- Returns:
- A list of dictionaries, where each dictionary
contains ‘name’, ‘path’, and ‘type’ (‘native’).
- Return type:
List[Dict[str, str]]
- register_app_event_listener(event_name: str, callback: Callable, listening_plugin_name: str)
Registers a callback function from a plugin to listen for an event.
- Parameters:
event_name (str) – The name of the event to listen for.
callback (Callable) – The function/method in the listening plugin that will be called when the specified event is triggered.
listening_plugin_name (str) – The name of the plugin registering the listener. Used for logging and context.
- reload()
Unloads all currently active plugins and then reloads all plugins.
This method provides a way to refresh the plugin system without restarting the entire application. It involves:
Dispatching the
on_unloadevent to all currently loaded plugins (viadispatch_event()).Clearing all registered custom event listeners from
self._event_listeners(as the plugins that registered them are being unloaded).Calling
load_plugins()to re-run the discovery, synchronization, and loading process for all plugins based on the current disk state andplugins.jsonconfiguration.
- dispatch_event(target_plugin: PluginBase, event_name: str, *args, **kwargs)
Dispatches an event to a specific plugin instance.
Executes listeners registered via @app_event for this specific event and the wildcard * event. It also includes backwards compatibility for legacy plugins that override before_…, after_… or on_any_event methods directly.
- Parameters:
target_plugin (
PluginBase) – The plugin instance to dispatch to.event_name (str) – The name of the event.
*args (Any) – Positional arguments to pass to the event handlers.
**kwargs (Any) – Keyword arguments to pass to the event handlers.
- async dispatch_event_async(target_plugin: PluginBase, event_name: str, *args, **kwargs)
Asynchronously dispatches an event to a specific plugin instance.
Executes listeners registered via @app_event for this specific event and the wildcard * event. It also includes backwards compatibility for legacy plugins.
- Parameters:
target_plugin (
PluginBase) – The plugin instance to dispatch to.event_name (str) – The name of the event.
*args (Any) – Positional arguments to pass.
**kwargs (Any) – Keyword arguments to pass.
- trigger_event(event_name: str, *args: Any, **kwargs: Any)
Triggers a standard application event on all loaded plugins.
This method iterates through all currently loaded and active plugins (in
self.plugins) and callsdispatch_event()for each one. It includes a granular re-entrancy protection mechanism using_event_context(athreading.localstack) and event instance keys generated by_generate_event_key()(based onEVENT_IDENTITY_KEYS). This prevents infinite loops if an event handler triggers an action that causes the same specific event instance to be dispatched again within the same call stack.- Parameters:
event_name (str) – The name of the event to trigger (e.g., “before_server_start”).
*args (Any) – Positional arguments to pass to each plugin’s event handler.
**kwargs (Any) – Keyword arguments to pass to each plugin’s event handler. Some of these may be used by
_generate_event_key()to identify the event instance.
- async trigger_event_async(event_name: str, *args: Any, **kwargs: Any)
Asynchronously triggers a standard application event on all loaded plugins.
This method works identically to trigger_event, but correctly handles and awaits asynchronous event handlers in plugins using dispatch_event_async.
- Parameters:
event_name (str) – The name of the event to trigger.
*args (Any) – Positional arguments to pass to each plugin’s event handler.
**kwargs (Any) – Keyword arguments to pass to each plugin’s event handler.
- trigger_guarded_event(event: str, *args, **kwargs)
Triggers a standard application event only if not in a guarded child process.
This method checks for the presence of the
GUARD_VARIABLEenvironment variable (usingos.environ.get). If this variable is set (indicating the current process might be a specially managed child process, like one launched for detached server operation, where certain global events should not be re-triggered), the event dispatch is skipped. Otherwise, it callstrigger_event().- Parameters:
event_name (str) – The name of the event to trigger.
*args (Any) – Positional arguments for the event handler.
**kwargs (Any) – Keyword arguments for the event handler.
- start_plugin_tasks()
Starts background tasks decorated with @task_loop for all loaded plugins.