improved signal handling

This commit is contained in:
2025-03-05 23:58:17 +01:00
parent 29e6fb5c50
commit 5e0145ec21
4 changed files with 31 additions and 14 deletions
+8 -2
View File
@@ -22,9 +22,15 @@ class TriggerTuple(NamedTuple):
class Config: class Config:
def __init__(self, basepath: Path) -> None: def __init__(self, _basepath: Optional[Path] = None) -> None:
self.basepath = basepath self._basepath = _basepath
self.config = ArgumentsParser().parser.config self.config = ArgumentsParser().parser.config
@cached_property
def basepath(self) -> Path:
if self._basepath is None:
return Path(__file__).parent
return self._basepath
@cached_property @cached_property
def root(self) -> etree._ElementTree: def root(self) -> etree._ElementTree:
@@ -15,8 +15,8 @@ def main() -> None:
async def _main() -> None: async def _main() -> None:
basepath = Path(__file__).parent.resolve() cwd = Path.cwd()
config = Config(basepath) config = Config(cwd)
log = getLogger('main', loglevel=config.loglevel.upper()) log = getLogger('main', loglevel=config.loglevel.upper())
if config.testmode: if config.testmode:
log.warning("starting in testmode, cpu adjustments have been disabled") log.warning("starting in testmode, cpu adjustments have been disabled")
+20 -9
View File
@@ -3,15 +3,16 @@ from cpu_governor_auto_adjust.config import Config
from cpu_governor_auto_adjust.trigger import Trigger from cpu_governor_auto_adjust.trigger import Trigger
from cpu_governor_auto_adjust.governor import GovernorControl, Governor, _governor_list from cpu_governor_auto_adjust.governor import GovernorControl, Governor, _governor_list
import asyncio import asyncio
import signal
from asyncio import Task from asyncio import Task
from functools import cached_property from functools import cached_property, partial
class TriggerScheduler(AppClass): class TriggerScheduler(AppClass):
def __init__(self, _config: Config) -> None: def __init__(self, _config: Config) -> None:
super().__init__(_config) super().__init__(_config)
self.tasks: list[Task] = []
self.running_triggers: list[Trigger] = [] self.running_triggers: list[Trigger] = []
self.loop = asyncio.get_event_loop()
@cached_property @cached_property
def governor_control(self) -> GovernorControl: def governor_control(self) -> GovernorControl:
@@ -44,24 +45,34 @@ class TriggerScheduler(AppClass):
def start_trigger(self, _trigger: Trigger) -> None: def start_trigger(self, _trigger: Trigger) -> None:
"""Start a new trigger.""" """Start a new trigger."""
if _trigger.config.type == "callback": if _trigger.config.type == "callback":
task = asyncio.create_task(self.callback_trigger(_trigger)) self.loop.create_task(self.callback_trigger(_trigger))
else: else:
task = asyncio.create_task(self.run_once_trigger(_trigger)) self.loop.create_task(self.run_once_trigger(_trigger))
self.running_triggers.append(_trigger) self.running_triggers.append(_trigger)
self.tasks.append(task)
async def stop_triggers(self) -> None: async def stop_triggers(self) -> None:
"""Stop all triggers.""" """Stop all triggers."""
for task in self.tasks: tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
for task in tasks:
self.log.debug("canceling trigger task: %s", task.get_coro())
task.cancel() task.cancel()
await asyncio.gather(*self.tasks, return_exceptions=True) await asyncio.gather(*tasks, return_exceptions=True)
self.loop.stop()
async def run(self) -> None: async def run(self) -> None:
"""Run the scheduler and keep it alive until stopped.""" """Run the scheduler and keep it alive until stopped."""
def signal_handler(sig):
self.log.info("received signal: %s", sig)
self.log.info("Exiting, stopping all triggers")
self.loop.create_task(self.stop_triggers())
for sig in [signal.SIGINT, signal.SIGTERM]:
self.loop.add_signal_handler(sig, partial(signal_handler, sig=signal.SIGINT))
try: try:
while True: while True:
self.establish_preferred_governor() self.establish_preferred_governor()
await asyncio.sleep(1) # Keep the main function alive await asyncio.sleep(1) # Keep the main function alive
except asyncio.exceptions.CancelledError: except asyncio.exceptions.CancelledError:
self.log.info("Exiting, stopping all triggers") pass
await self.stop_triggers()
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "cpu_governor_auto_adjust" name = "cpu_governor_auto_adjust"
version = "0.1.11" version = "0.1.13"
description = "This application has been developed to automatically change cpu governor based on certain triggers." description = "This application has been developed to automatically change cpu governor based on certain triggers."
authors = [ authors = [
{ name = "Martin Reurekas", email = "martin@semrks.nl" } { name = "Martin Reurekas", email = "martin@semrks.nl" }