improved signal handling
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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
@@ -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" }
|
||||||
|
|||||||
Reference in New Issue
Block a user