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:
def __init__(self, basepath: Path) -> None:
self.basepath = basepath
def __init__(self, _basepath: Optional[Path] = None) -> None:
self._basepath = _basepath
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
def root(self) -> etree._ElementTree:
@@ -15,8 +15,8 @@ def main() -> None:
async def _main() -> None:
basepath = Path(__file__).parent.resolve()
config = Config(basepath)
cwd = Path.cwd()
config = Config(cwd)
log = getLogger('main', loglevel=config.loglevel.upper())
if config.testmode:
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.governor import GovernorControl, Governor, _governor_list
import asyncio
import signal
from asyncio import Task
from functools import cached_property
from functools import cached_property, partial
class TriggerScheduler(AppClass):
def __init__(self, _config: Config) -> None:
super().__init__(_config)
self.tasks: list[Task] = []
self.running_triggers: list[Trigger] = []
self.loop = asyncio.get_event_loop()
@cached_property
def governor_control(self) -> GovernorControl:
@@ -44,24 +45,34 @@ class TriggerScheduler(AppClass):
def start_trigger(self, _trigger: Trigger) -> None:
"""Start a new trigger."""
if _trigger.config.type == "callback":
task = asyncio.create_task(self.callback_trigger(_trigger))
self.loop.create_task(self.callback_trigger(_trigger))
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.tasks.append(task)
async def stop_triggers(self) -> None:
"""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()
await asyncio.gather(*self.tasks, return_exceptions=True)
await asyncio.gather(*tasks, return_exceptions=True)
self.loop.stop()
async def run(self) -> None:
"""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:
while True:
self.establish_preferred_governor()
await asyncio.sleep(1) # Keep the main function alive
except asyncio.exceptions.CancelledError:
self.log.info("Exiting, stopping all triggers")
await self.stop_triggers()
pass