# -*- coding: utf-8 -*- """ Basis-Interface für alle Trixy-Services. Definiert den Lebenszyklus und die Struktur von Services. """ from abc import ABC, abstractmethod from typing import TYPE_CHECKING, ClassVar from trixy_core.service.enums import ServicePriority, ServiceGroup, ServiceState if TYPE_CHECKING: from trixy_core.application import IApplication class IService(ABC): """ Abstrakte Basisklasse für alle Trixy-Services. Jeder Service muss diese Klasse erweitern und die abstrakten Methoden implementieren. Der ServiceContainer verwaltet den Lebenszyklus basierend auf PRIORITY und DEPENDENCIES. Klassenattribute: PRIORITY: Startreihenfolge (niedrigere Werte = früher) GROUP: Kategorisierung des Services DEPENDENCIES: Liste der benötigten Service-Namen NAME: Eindeutiger Name des Services (Standard: Klassenname) """ # Klassenattribute (überschreiben in Unterklassen) PRIORITY: ClassVar[ServicePriority] = ServicePriority.OPTIONAL GROUP: ClassVar[ServiceGroup] = ServiceGroup.UTILITY DEPENDENCIES: ClassVar[list[str]] = [] NAME: ClassVar[str] = "" def __init__(self, application: "IApplication") -> None: """ Initialisiert den Service. Args: application: Referenz zur Hauptanwendung """ self._application = application self._state = ServiceState.STOPPED @property def application(self) -> "IApplication": """Gibt die Anwendungsreferenz zurück.""" return self._application @property def state(self) -> ServiceState: """Gibt den aktuellen Service-Zustand zurück.""" return self._state @property def name(self) -> str: """Gibt den Service-Namen zurück.""" return self.NAME or self.__class__.__name__ @property def is_running(self) -> bool: """Prüft, ob der Service läuft.""" return self._state == ServiceState.RUNNING def _set_state(self, state: ServiceState) -> None: """Setzt den internen Zustand.""" self._state = state async def on_pre_start(self) -> None: """ Hook vor dem Start des Services. Wird aufgerufen, bevor start() ausgeführt wird. Kann für Vorbereitungen genutzt werden. """ pass async def on_post_start(self) -> None: """ Hook nach dem Start des Services. Wird aufgerufen, nachdem start() erfolgreich war. """ pass async def on_pre_stop(self) -> None: """ Hook vor dem Stoppen des Services. Wird aufgerufen, bevor stop() ausgeführt wird. """ pass async def on_post_stop(self) -> None: """ Hook nach dem Stoppen des Services. Wird aufgerufen, nachdem stop() ausgeführt wurde. """ pass async def on_dependency_ready(self, dependency_name: str) -> None: """ Hook wenn eine Abhängigkeit bereit ist. Wird aufgerufen, wenn ein Service aus DEPENDENCIES erfolgreich gestartet wurde. Args: dependency_name: Name des gestarteten Abhängigkeits-Services """ pass @abstractmethod async def start(self) -> None: """ Startet den Service. Muss von Unterklassen implementiert werden. Raises: Exception: Bei Fehlern während des Starts """ pass @abstractmethod async def stop(self) -> None: """ Stoppt den Service. Muss von Unterklassen implementiert werden. Sollte Ressourcen freigeben und sauber herunterfahren. """ pass async def health_check(self) -> bool: """ Führt eine Gesundheitsprüfung durch. Kann von Unterklassen überschrieben werden, um spezifische Prüfungen durchzuführen. Returns: True wenn der Service gesund ist, sonst False """ return self._state == ServiceState.RUNNING