From a652845843c178a451d1ab49a5c31ed2fd9f6bfa Mon Sep 17 00:00:00 2001 From: Eric Callahan Date: Sun, 26 Dec 2021 11:13:30 -0500 Subject: [PATCH] moonraker: add register_component() method Allow base modules to register themselves as components during initialization. This makes them accessible via lookup_component() across the entire application. Signed-off-by: Eric Callahan --- moonraker/app.py | 26 +++++++++++++------------- moonraker/components/proc_stats.py | 8 +++++--- moonraker/moonraker.py | 17 +++++++++++------ moonraker/websockets.py | 8 +++----- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/moonraker/app.py b/moonraker/app.py index a815054..da2757b 100644 --- a/moonraker/app.py +++ b/moonraker/app.py @@ -192,7 +192,7 @@ class MoonrakerApp: 'serve_traceback': self.debug, 'websocket_ping_interval': 10, 'websocket_ping_timeout': 30, - 'parent': self, + 'server': self.server, 'default_handler_class': AuthorizedErrorHandler, 'default_handler_args': {}, 'log_function': self.log_request @@ -216,6 +216,12 @@ class MoonrakerApp: "klippy.log", DEFAULT_KLIPPY_LOG_PATH, force=True) self.register_upload_handler("/server/files/upload") + # Register Server Components + self.server.register_component("application", self) + self.server.register_component("websockets", self.wsm) + self.server.register_component("internal_transport", + self.internal_transport) + def _get_path_option(self, config: ConfigHelper, option: str) -> str: path: Optional[str] = config.get(option, None) if path is None: @@ -265,12 +271,6 @@ class MoonrakerApp: def get_server(self) -> Server: return self.server - def get_websocket_manager(self) -> WebsocketManager: - return self.wsm - - def get_internal_transport(self) -> InternalTransport: - return self.internal_transport - async def close(self) -> None: if self.http_server is not None: self.http_server.stop() @@ -412,13 +412,13 @@ class MoonrakerApp: class AuthorizedRequestHandler(tornado.web.RequestHandler): def initialize(self) -> None: - self.server: Server = self.settings['parent'].get_server() + self.server: Server = self.settings['server'] def set_default_headers(self) -> None: origin: Optional[str] = self.request.headers.get("Origin") # it is necessary to look up the parent app here, # as initialize() may not yet be called - server: Server = self.settings['parent'].get_server() + server: Server = self.settings['server'] auth: AuthComp = server.lookup_component('authorization', None) self.cors_enabled = False if auth is not None: @@ -448,8 +448,8 @@ class AuthorizedRequestHandler(tornado.web.RequestHandler): except Exception: pass else: - parent: MoonrakerApp = self.settings['parent'] - wsm: WebsocketManager = parent.get_websocket_manager() + wsm: WebsocketManager = self.server.lookup_component( + "websockets") conn = wsm.get_websocket(conn_id) return conn @@ -468,13 +468,13 @@ class AuthorizedFileHandler(tornado.web.StaticFileHandler): default_filename: Optional[str] = None ) -> None: super(AuthorizedFileHandler, self).initialize(path, default_filename) - self.server: Server = self.settings['parent'].get_server() + self.server: Server = self.settings['server'] def set_default_headers(self) -> None: origin: Optional[str] = self.request.headers.get("Origin") # it is necessary to look up the parent app here, # as initialize() may not yet be called - server: Server = self.settings['parent'].get_server() + server: Server = self.settings['server'] auth: AuthComp = server.lookup_component('authorization', None) self.cors_enabled = False if auth is not None: diff --git a/moonraker/components/proc_stats.py b/moonraker/components/proc_stats.py index 12d801d..9a91f94 100644 --- a/moonraker/components/proc_stats.py +++ b/moonraker/components/proc_stats.py @@ -24,7 +24,7 @@ from typing import ( ) if TYPE_CHECKING: from confighelper import ConfigHelper - from websockets import WebRequest + from websockets import WebRequest, WebsocketManager from . import shell_command from .machine import Machine @@ -95,7 +95,8 @@ class ProcStats: ts = await self._check_throttled_state() cpu_temp = await self.event_loop.run_in_thread( self._get_cpu_temperature) - websocket_count = self.server.get_websocket_manager().get_count() + wsm: WebsocketManager = self.server.lookup_component("websockets") + websocket_count = wsm.get_count() return { 'moonraker_stats': list(self.proc_stat_queue), 'throttled_state': ts, @@ -140,7 +141,8 @@ class ProcStats: 'mem_units': mem_units } self.proc_stat_queue.append(result) - websocket_count = self.server.get_websocket_manager().get_count() + wsm: WebsocketManager = self.server.lookup_component("websockets") + websocket_count = wsm.get_count() self.server.send_event("proc_stats:proc_stat_update", { 'moonraker_stats': result, 'cpu_temp': cpu_temp, diff --git a/moonraker/moonraker.py b/moonraker/moonraker.py index 9a4ecc6..399071e 100755 --- a/moonraker/moonraker.py +++ b/moonraker/moonraker.py @@ -32,14 +32,13 @@ from typing import ( Optional, Callable, Coroutine, - Tuple, Dict, List, Union, TypeVar, ) if TYPE_CHECKING: - from websockets import WebRequest, Subscribable + from websockets import WebRequest, Subscribable, WebsocketManager from components.data_store import DataStore from components.klippy_apis import KlippyAPI from components.file_manager.file_manager import FileManager @@ -110,6 +109,7 @@ class Server: self.klippy_state: str = "disconnected" self.klippy_disconnect_evt: Optional[asyncio.Event] = None self.connection_init_lock: asyncio.Lock = asyncio.Lock() + self.components: Dict[str, Any] = {} self.subscriptions: Dict[Subscribable, Dict[str, Any]] = {} self.failed_components: List[str] = [] self.warnings: List[str] = [] @@ -120,7 +120,6 @@ class Server: self.register_endpoint = app.register_local_handler self.register_static_file_handler = app.register_static_file_handler self.register_upload_handler = app.register_upload_handler - self.get_websocket_manager = app.get_websocket_manager self.register_api_transport = app.register_api_transport self.register_endpoint( @@ -150,7 +149,6 @@ class Server: need_klippy_reg=False) # Component initialization - self.components: Dict[str, Any] = {} self._load_components(config) self.klippy_apis: KlippyAPI = self.lookup_component('klippy_apis') config.validate_config() @@ -275,11 +273,17 @@ class Server: if component_name not in self.failed_components: self.failed_components.append(component_name) + def register_component(self, component_name: str, component: Any) -> None: + if component_name in self.components: + raise self.error( + f"Component '{component_name}' already registered") + self.components[component_name] = component + def register_notification(self, event_name: str, notify_name: Optional[str] = None ) -> None: - wsm = self.get_websocket_manager() + wsm: WebsocketManager = self.lookup_component("websockets") wsm.register_notification(event_name, notify_name) def register_event_handler(self, @@ -682,6 +686,7 @@ class Server: reg_dirs = [] if file_manager is not None: reg_dirs = file_manager.get_registered_dirs() + wsm: WebsocketManager = self.lookup_component('websockets') return { 'klippy_connected': self.klippy_connection.is_connected(), 'klippy_state': self.klippy_state, @@ -689,7 +694,7 @@ class Server: 'failed_components': self.failed_components, 'registered_directories': reg_dirs, 'warnings': self.warnings, - 'websocket_count': self.get_websocket_manager().get_count(), + 'websocket_count': wsm.get_count(), 'moonraker_version': self.app_args['software_version'] } diff --git a/moonraker/websockets.py b/moonraker/websockets.py index 2bf433b..6ef6650 100644 --- a/moonraker/websockets.py +++ b/moonraker/websockets.py @@ -27,8 +27,7 @@ from typing import ( ) if TYPE_CHECKING: from moonraker import Server - from eventloop import EventLoop - from app import APIDefinition, MoonrakerApp + from app import APIDefinition import components.authorization _T = TypeVar("_T") _C = TypeVar("_C", str, bool, float, int) @@ -381,10 +380,9 @@ class WebsocketManager(APITransport): class WebSocket(WebSocketHandler, Subscribable): def initialize(self) -> None: - app: MoonrakerApp = self.settings['parent'] - self.server = app.get_server() + self.server: Server = self.settings['server'] self.event_loop = self.server.get_event_loop() - self.wsm = app.get_websocket_manager() + self.wsm: WebsocketManager = self.server.lookup_component("websockets") self.rpc = self.wsm.rpc self.uid = id(self) self.is_closed: bool = False