]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
manager: controller: getting SubprocessStatus from particular Subprocess
authorAleš Mrázek <ales.mrazek@nic.cz>
Fri, 17 May 2024 12:03:45 +0000 (14:03 +0200)
committerAleš Mrázek <ales.mrazek@nic.cz>
Tue, 2 Jul 2024 12:07:48 +0000 (14:07 +0200)
manager/knot_resolver_manager/kres_manager.py
manager/knot_resolver_manager/kresd_controller/interface.py
manager/knot_resolver_manager/kresd_controller/supervisord/__init__.py

index 8507a9fc1ea0ed69298d5a519b4c95a7847734ae..29e43f7a201fbefdd59f4569e806179900352713 100644 (file)
@@ -344,13 +344,13 @@ class KresManager:  # pylint: disable=too-many-instance-attributes
                         invoke_callback = True
                         continue
 
-                    if detected_subprocesses[eid] is SubprocessStatus.FAILED:
-                        logger.error("Subprocess '%s' is failed.", eid)
+                    if detected_subprocesses[eid] is SubprocessStatus.FATAL:
+                        logger.error("Subprocess '%s' is in FATAL state!", eid)
                         invoke_callback = True
                         continue
 
                     if detected_subprocesses[eid] is SubprocessStatus.UNKNOWN:
-                        logger.warning("Subprocess '%s' is in unknown state!", eid)
+                        logger.warning("Subprocess '%s' is in UNKNOWN state!", eid)
 
                 non_registered_ids = detected_subprocesses.keys() - set(expected_ids)
                 if len(non_registered_ids) != 0:
index 3df229e6944a27b054e377ce27e2460969c43c3a..bd1ba59fdb4916b47323238436d101ba41462a54 100644 (file)
@@ -25,6 +25,13 @@ class SubprocessType(Enum):
     GC = auto()
 
 
+class SubprocessStatus(Enum):
+    RUNNING = auto()
+    FATAL = auto()
+    EXITED = auto()
+    UNKNOWN = auto()
+
+
 T = TypeVar("T", bound="KresID")
 
 
@@ -185,6 +192,10 @@ class Subprocess(ABC):
     async def _restart(self) -> None:
         pass
 
+    @abstractmethod
+    def status(self) -> SubprocessStatus:
+        pass
+
     @property
     def type(self) -> SubprocessType:
         return self.id.subprocess_type
@@ -228,13 +239,6 @@ class Subprocess(ABC):
                     await writer.wait_closed()  # type: ignore
 
 
-class SubprocessStatus(Enum):
-    RUNNING = auto()
-    FAILED = auto()
-    EXITED = auto()
-    UNKNOWN = auto()
-
-
 class SubprocessController(ABC):
     """
     The common Subprocess Controller interface. This is what KresManager requires and what has to be implemented by all
index d0a6c63337ea63f475042bc5b8b1c3f661ad5744..5fb4d81d5bb166cd4a9559541e04de24d0690806 100644 (file)
@@ -139,35 +139,39 @@ def _create_fast_proxy(config: KresConfig) -> Any:
     return getattr(proxy, "fast")
 
 
+def _convert_subprocess_status(proc: Any) -> SubprocessStatus:
+    conversion_tbl = {
+        # "STOPPED": None,  # filtered out elsewhere
+        "STARTING": SubprocessStatus.RUNNING,
+        "RUNNING": SubprocessStatus.RUNNING,
+        "BACKOFF": SubprocessStatus.RUNNING,
+        "STOPPING": SubprocessStatus.RUNNING,
+        "EXITED": SubprocessStatus.EXITED,
+        "FATAL": SubprocessStatus.FATAL,
+        "UNKNOWN": SubprocessStatus.UNKNOWN,
+    }
+
+    if proc["statename"] in conversion_tbl:
+        status = conversion_tbl[proc["statename"]]
+    else:
+        logger.warning(f"Unknown supervisord process state {proc['statename']}")
+        status = SubprocessStatus.UNKNOWN
+    return status
+
+
 def _list_running_subprocesses(config: KresConfig) -> Dict[SupervisordKresID, SubprocessStatus]:
-    supervisord = _create_supervisord_proxy(config)
-    processes: Any = supervisord.getAllProcessInfo()
-
-    def convert(proc: Any) -> SubprocessStatus:
-        conversion_tbl = {
-            # "STOPPED": None,  # filtered out elsewhere
-            "STARTING": SubprocessStatus.RUNNING,
-            "RUNNING": SubprocessStatus.RUNNING,
-            "BACKOFF": SubprocessStatus.RUNNING,
-            "STOPPING": SubprocessStatus.RUNNING,
-            "EXITED": SubprocessStatus.EXITED,
-            "FATAL": SubprocessStatus.FAILED,
-            "UNKNOWN": SubprocessStatus.UNKNOWN,
-        }
-
-        if proc["statename"] in conversion_tbl:
-            status = conversion_tbl[proc["statename"]]
-        else:
-            logger.warning(f"Unknown supervisord process state {proc['statename']}")
-            status = SubprocessStatus.UNKNOWN
-        return status
+    try:
+        supervisord = _create_supervisord_proxy(config)
+        processes: Any = supervisord.getAllProcessInfo()
+    except Fault as e:
+        raise SubprocessControllerException(f"failed to get info from all running processes: {e}") from e
 
     # there will be a manager process as well, but we don't want to report anything on ourselves
     processes = [pr for pr in processes if pr["name"] != "manager"]
 
     # convert all the names
     return {
-        SupervisordKresID.from_string(f"{pr['group']}:{pr['name']}"): convert(pr)
+        SupervisordKresID.from_string(f"{pr['group']}:{pr['name']}"): _convert_subprocess_status(pr)
         for pr in processes
         if pr["statename"] != "STOPPED"
     }
@@ -190,6 +194,14 @@ class SupervisordSubprocess(Subprocess):
     def name(self):
         return str(self.id)
 
+    def status(self) -> SubprocessStatus:
+        try:
+            supervisord = _create_supervisord_proxy(self._config)
+            status = supervisord.getProcessInfo(self.name)
+        except Fault as e:
+            raise SubprocessControllerException(f"failed to get status from '{self.id}' process: {e}") from e
+        return _convert_subprocess_status(status)
+
     @async_in_a_thread
     def _start(self) -> None:
         # +1 for canary process (same as in config_file.py)