proc_stats: add stat callback registration
This allows other components to be register callbacks that will be executed in the stat update timer. This is useful for methods that wish to poll subprocess commands, as its desireable to prevent multiple subprocesses from running simultaneously. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
f4c5e808c3
commit
9b6161a6b0
|
@ -16,6 +16,8 @@ from collections import deque
|
||||||
# Annotation imports
|
# Annotation imports
|
||||||
from typing import (
|
from typing import (
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
|
Awaitable,
|
||||||
|
Callable,
|
||||||
Deque,
|
Deque,
|
||||||
Any,
|
Any,
|
||||||
List,
|
List,
|
||||||
|
@ -27,7 +29,7 @@ if TYPE_CHECKING:
|
||||||
from confighelper import ConfigHelper
|
from confighelper import ConfigHelper
|
||||||
from websockets import WebRequest, WebsocketManager
|
from websockets import WebRequest, WebsocketManager
|
||||||
from . import shell_command
|
from . import shell_command
|
||||||
from .machine import Machine
|
STAT_CALLBACK = Callable[[int], Optional[Awaitable]]
|
||||||
|
|
||||||
VC_GEN_CMD_FILE = "/usr/bin/vcgencmd"
|
VC_GEN_CMD_FILE = "/usr/bin/vcgencmd"
|
||||||
STATM_FILE_PATH = "/proc/self/smaps_rollup"
|
STATM_FILE_PATH = "/proc/self/smaps_rollup"
|
||||||
|
@ -55,7 +57,6 @@ class ProcStats:
|
||||||
def __init__(self, config: ConfigHelper) -> None:
|
def __init__(self, config: ConfigHelper) -> None:
|
||||||
self.server = config.get_server()
|
self.server = config.get_server()
|
||||||
self.event_loop = self.server.get_event_loop()
|
self.event_loop = self.server.get_event_loop()
|
||||||
self.machine: Machine = self.server.load_component(config, 'machine')
|
|
||||||
self.watchdog = Watchdog(self)
|
self.watchdog = Watchdog(self)
|
||||||
self.stat_update_timer = self.event_loop.register_timer(
|
self.stat_update_timer = self.event_loop.register_timer(
|
||||||
self._handle_stat_update)
|
self._handle_stat_update)
|
||||||
|
@ -89,9 +90,13 @@ class ProcStats:
|
||||||
self.last_net_stats: Dict[str, Dict[str, Any]] = {}
|
self.last_net_stats: Dict[str, Dict[str, Any]] = {}
|
||||||
self.last_cpu_stats: Dict[str, Tuple[int, int]] = {}
|
self.last_cpu_stats: Dict[str, Tuple[int, int]] = {}
|
||||||
self.cpu_usage: Dict[str, float] = {}
|
self.cpu_usage: Dict[str, float] = {}
|
||||||
|
self.stat_callbacks: List[STAT_CALLBACK] = []
|
||||||
self.stat_update_timer.start()
|
self.stat_update_timer.start()
|
||||||
self.watchdog.start()
|
self.watchdog.start()
|
||||||
|
|
||||||
|
def register_stat_callback(self, callback: STAT_CALLBACK) -> None:
|
||||||
|
self.stat_callbacks.append(callback)
|
||||||
|
|
||||||
async def _handle_stat_request(self,
|
async def _handle_stat_request(self,
|
||||||
web_request: WebRequest
|
web_request: WebRequest
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
|
@ -156,11 +161,7 @@ class ProcStats:
|
||||||
'system_cpu_usage': self.cpu_usage,
|
'system_cpu_usage': self.cpu_usage,
|
||||||
'websocket_connections': websocket_count
|
'websocket_connections': websocket_count
|
||||||
})
|
})
|
||||||
self.last_update_time = update_time
|
if not self.update_sequence % THROTTLE_CHECK_INTERVAL:
|
||||||
self.last_proc_time = proc_time
|
|
||||||
self.update_sequence += 1
|
|
||||||
if self.update_sequence == THROTTLE_CHECK_INTERVAL:
|
|
||||||
self.update_sequence = 0
|
|
||||||
if self.vcgencmd is not None:
|
if self.vcgencmd is not None:
|
||||||
ts = await self._check_throttled_state()
|
ts = await self._check_throttled_state()
|
||||||
cur_throttled = ts['bits']
|
cur_throttled = ts['bits']
|
||||||
|
@ -171,8 +172,13 @@ class ProcStats:
|
||||||
self.server.send_event("proc_stats:cpu_throttled", ts)
|
self.server.send_event("proc_stats:cpu_throttled", ts)
|
||||||
self.last_throttled = cur_throttled
|
self.last_throttled = cur_throttled
|
||||||
self.total_throttled |= cur_throttled
|
self.total_throttled |= cur_throttled
|
||||||
await self.machine.parse_network_interfaces()
|
for cb in self.stat_callbacks:
|
||||||
await self.machine.update_service_status()
|
ret = cb(self.update_sequence)
|
||||||
|
if ret is not None:
|
||||||
|
await ret
|
||||||
|
self.last_update_time = update_time
|
||||||
|
self.last_proc_time = proc_time
|
||||||
|
self.update_sequence += 1
|
||||||
return eventtime + STAT_UPDATE_TIME
|
return eventtime + STAT_UPDATE_TIME
|
||||||
|
|
||||||
async def _check_throttled_state(self) -> Dict[str, Any]:
|
async def _check_throttled_state(self) -> Dict[str, Any]:
|
||||||
|
|
Loading…
Reference in New Issue