Skip to content

Commit 8816ce2

Browse files
committed
move plugins init and stop from main to plugins
1 parent d1cffbb commit 8816ce2

File tree

6 files changed

+421
-40
lines changed

6 files changed

+421
-40
lines changed

docs/plugins/plugins.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ The `start` and `stop` functions must have the following signatures:
9494
```python
9595
async def init(controller_enabled: bool, executor_enabled: bool): ...
9696

97-
async def stop(): ...
97+
async def stop(controller_enabled: bool, executor_enabled: bool): ...
9898
```
9999

100100
## Queues

src/main.py

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,6 @@
2222
_logger = logging.getLogger("main")
2323

2424

25-
async def init_plugins_services(controller_enabled: bool, executor_enabled: bool) -> None:
26-
"""Initialize the plugins services"""
27-
for plugin_name, plugin in plugins.loaded_plugins.items():
28-
_logger.info(f"Loading plugin '{plugin_name}'")
29-
30-
plugin_services = getattr(plugin, "services", None)
31-
if plugin_services is None:
32-
_logger.info(f"Plugin '{plugin_name}' has no services")
33-
continue
34-
35-
for service_name in plugin_services.__all__:
36-
service = getattr(plugin_services, service_name)
37-
if hasattr(service, "init"):
38-
await service.init(controller_enabled, executor_enabled)
39-
_logger.info(f"Service '{plugin_name}.{service_name}' initialized")
40-
else:
41-
_logger.warning(f"Service '{plugin_name}.{service_name}' has no 'init' function")
42-
43-
4425
async def init(controller_enabled: bool, executor_enabled: bool) -> None:
4526
"""Initialize the application dependencies. Some of the components will behave differently if
4627
they start with or without the controller."""
@@ -53,35 +34,23 @@ async def init(controller_enabled: bool, executor_enabled: bool) -> None:
5334
await http_server.init(controller_enabled)
5435

5536
plugins.load_plugins()
56-
await init_plugins_services(controller_enabled, executor_enabled)
37+
await plugins.services.init_plugin_services(controller_enabled, executor_enabled)
5738

5839
# The following modules depend on the plugins being loaded
5940
await databases.init()
6041
await message_queue.init()
6142

6243

63-
async def stop_plugins_services() -> None:
64-
"""Stop the plugins services"""
65-
for plugin_name, plugin in plugins.loaded_plugins.items():
66-
_logger.info(f"Stopping plugin '{plugin_name}'")
67-
68-
plugin_services = getattr(plugin, "services", None)
69-
if plugin_services is None:
70-
continue
71-
72-
for service_name in plugin_services.__all__:
73-
service = getattr(plugin_services, service_name)
74-
if hasattr(service, "stop"):
75-
await protected_task(service.stop())
76-
77-
78-
async def finish() -> None:
44+
async def finish(controller_enabled: bool, executor_enabled: bool) -> None:
7945
"""Finish the application, making sure any exception won't impact other closing tasks"""
8046
await protected_task(_logger, http_server.wait_stop())
8147
await protected_task(_logger, monitors_loader.wait_stop())
8248
await protected_task(_logger, databases.close())
8349
await protected_task(_logger, internal_database.close())
84-
await protected_task(_logger, plugins.services.stop())
50+
await protected_task(
51+
_logger,
52+
plugins.services.stop_plugin_services(controller_enabled, executor_enabled),
53+
)
8554

8655

8756
async def main() -> None:
@@ -103,7 +72,10 @@ async def main() -> None:
10372
tasks = [modes[mode]() for mode in operation_modes]
10473
await asyncio.gather(*tasks)
10574

106-
await finish()
75+
await finish(
76+
controller_enabled="controller" in operation_modes,
77+
executor_enabled="executor" in operation_modes,
78+
)
10779

10880

10981
if __name__ == "__main__":

src/plugins/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
from types import ModuleType
22

3+
from . import services
34
from .plugins_loader import load_plugins as __load_plugins
45

56
loaded_plugins: dict[str, ModuleType]
67

78

89
def load_plugins() -> dict[str, ModuleType]:
10+
"""Load the plugins and return it as a dictionary"""
911
global loaded_plugins
1012
loaded_plugins = __load_plugins()
1113
return loaded_plugins
14+
15+
16+
__all__ = [
17+
"load_plugins",
18+
"services",
19+
]

src/plugins/services.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import logging
2+
from types import ModuleType
3+
4+
from utils.exception_handling import protected_task
5+
6+
_logger = logging.getLogger("plugins.services")
7+
8+
9+
async def _plugin_service_run(
10+
plugin_name: str,
11+
plugin: ModuleType,
12+
function_name: str,
13+
controller_enabled: bool,
14+
executor_enabled: bool,
15+
) -> None:
16+
"""Run a function of a plugin service, used to initialize or stop the services"""
17+
plugin_services = getattr(plugin, "services", None)
18+
if plugin_services is None:
19+
_logger.info(f"Plugin '{plugin_name}' has no services")
20+
return
21+
22+
plugin_services_names = getattr(plugin_services, "__all__", None)
23+
if plugin_services_names is None:
24+
_logger.warning(f"Plugin '{plugin_name}' has no '__all__' attribute in services")
25+
return
26+
27+
for service_name in plugin_services_names:
28+
service = getattr(plugin_services, service_name, None)
29+
if service is None:
30+
_logger.warning(f"Service '{plugin_name}.{service_name}' not found")
31+
continue
32+
33+
target_function = getattr(service, function_name, None)
34+
if target_function is None:
35+
_logger.warning(
36+
f"Service '{plugin_name}.{service_name}' has no '{function_name}' function"
37+
)
38+
continue
39+
40+
_logger.info(f"Running '{plugin_name}.{service_name}.{function_name}'")
41+
await protected_task(_logger, target_function(controller_enabled, executor_enabled))
42+
43+
44+
async def init_plugin_services(controller_enabled: bool, executor_enabled: bool) -> None:
45+
"""Initialize the plugins services"""
46+
# Import loaded plugins here after all the plugins are loaded
47+
from . import load_plugins
48+
49+
for plugin_name, plugin in load_plugins().items():
50+
_logger.info(f"Starting plugin '{plugin_name}' services")
51+
await _plugin_service_run(plugin_name, plugin, "init", controller_enabled, executor_enabled)
52+
53+
54+
async def stop_plugin_services(controller_enabled: bool, executor_enabled: bool) -> None:
55+
"""Stop the plugins services"""
56+
# Import loaded plugins here after all the plugins are loaded
57+
from . import load_plugins
58+
59+
for plugin_name, plugin in load_plugins().items():
60+
_logger.info(f"Stopping plugin '{plugin_name}' services")
61+
await _plugin_service_run(plugin_name, plugin, "stop", controller_enabled, executor_enabled)

src/plugins/slack/services/websocket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ async def init(controller_enabled: bool, executor_enabled: bool) -> None: # pra
9696
await _handler.connect_async()
9797

9898

99-
async def stop() -> None: # pragma: no cover
99+
async def stop(controller_enabled: bool, executor_enabled: bool) -> None: # pragma: no cover
100100
global _handler
101101

102102
if _handler is not None:

0 commit comments

Comments
 (0)