made all triggers async

This commit is contained in:
2025-03-31 19:25:19 +02:00
parent a56c3ed36f
commit 9e62c1cd6b
7 changed files with 54 additions and 62 deletions
-6
View File
@@ -7,21 +7,18 @@
<trigger> <trigger>
<name>test_trigger1</name> <name>test_trigger1</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>sync</type>
<intervalInSeconds>1</intervalInSeconds> <intervalInSeconds>1</intervalInSeconds>
<governor>ondemand</governor> <governor>ondemand</governor>
</trigger> </trigger>
<trigger> <trigger>
<name>test_trigger2</name> <name>test_trigger2</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>sync</type>
<intervalInSeconds>3</intervalInSeconds> <intervalInSeconds>3</intervalInSeconds>
<governor>conservative</governor> <governor>conservative</governor>
</trigger> </trigger>
<trigger> <trigger>
<name>roon</name> <name>roon</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>async</type>
<intervalInSeconds>2</intervalInSeconds> <intervalInSeconds>2</intervalInSeconds>
<governor>performance</governor> <governor>performance</governor>
<customConfig> <customConfig>
@@ -36,7 +33,6 @@
<trigger> <trigger>
<name>wakeup</name> <name>wakeup</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>sync</type>
<intervalInSeconds>5</intervalInSeconds> <intervalInSeconds>5</intervalInSeconds>
<governor>conservative</governor> <governor>conservative</governor>
<customConfig> <customConfig>
@@ -47,7 +43,6 @@
<trigger> <trigger>
<name>cpu_load</name> <name>cpu_load</name>
<logLevel>Debug</logLevel> <logLevel>Debug</logLevel>
<type>sync</type>
<intervalInSeconds>5</intervalInSeconds> <intervalInSeconds>5</intervalInSeconds>
<governor>performance</governor> <governor>performance</governor>
<customConfig> <customConfig>
@@ -62,7 +57,6 @@
<trigger> <trigger>
<name>roon_arc</name> <name>roon_arc</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>async</type>
<intervalInSeconds>5</intervalInSeconds> <intervalInSeconds>5</intervalInSeconds>
<governor>performance</governor> <governor>performance</governor>
<customConfig> <customConfig>
-3
View File
@@ -13,7 +13,6 @@ from cpu_governor_auto_adjust.logger import getLogger
class TriggerTuple(NamedTuple): class TriggerTuple(NamedTuple):
name: str name: str
loglevel: str loglevel: str
type: str
interval_in_seconds: int interval_in_seconds: int
governor: str governor: str
custom_config: OrderedDict[str, Any] custom_config: OrderedDict[str, Any]
@@ -84,7 +83,6 @@ class Config:
for trigger_elem in _trigger_elements: for trigger_elem in _trigger_elements:
name = self._get_single_text_value_from_xpath('name', trigger_elem) name = self._get_single_text_value_from_xpath('name', trigger_elem)
loglevel = self._get_single_text_value_from_xpath('logLevel', trigger_elem) loglevel = self._get_single_text_value_from_xpath('logLevel', trigger_elem)
type = self._get_single_text_value_from_xpath('type', trigger_elem)
interval_in_seconds = self._get_single_text_value_from_xpath('intervalInSeconds', trigger_elem) interval_in_seconds = self._get_single_text_value_from_xpath('intervalInSeconds', trigger_elem)
governor = self._get_single_text_value_from_xpath('governor', trigger_elem) governor = self._get_single_text_value_from_xpath('governor', trigger_elem)
try: try:
@@ -96,7 +94,6 @@ class Config:
_new_trigger = TriggerTuple( _new_trigger = TriggerTuple(
name=name, name=name,
loglevel=loglevel, loglevel=loglevel,
type=type,
interval_in_seconds=int(interval_in_seconds), interval_in_seconds=int(interval_in_seconds),
governor=governor, governor=governor,
custom_config=custom_config custom_config=custom_config
+1 -15
View File
@@ -49,23 +49,9 @@ class TriggerScheduler(AppClass):
self.log.debug("callback trigger %s, state: %s", _trigger.name, _trigger.trigger_state) self.log.debug("callback trigger %s, state: %s", _trigger.name, _trigger.trigger_state)
await asyncio.sleep(_trigger.config.interval_in_seconds) await asyncio.sleep(_trigger.config.interval_in_seconds)
async def sync_trigger(self, _trigger: Trigger) -> None:
"""Run a trigger with a specific name at a given interval."""
while True:
start = monotonic()
_trigger.run()
end = monotonic()
self.log.debug("run once trigger %s, state: %s, duration: %.3f ms", _trigger.name, _trigger.trigger_state, (end - start) * 1000)
await asyncio.sleep(_trigger.config.interval_in_seconds)
async def start_trigger(self, _trigger: Trigger) -> None: async def start_trigger(self, _trigger: Trigger) -> None:
"""Start a new trigger.""" """Start a new trigger."""
if _trigger.config.type == "async": self.loop.create_task(self.async_trigger(_trigger))
self.loop.create_task(self.async_trigger(_trigger))
elif _trigger.config.type == "sync":
self.loop.create_task(self.sync_trigger(_trigger))
else:
raise ValueError(f"unknown trigger type: {_trigger.config.type}")
self.running_triggers.append(_trigger) self.running_triggers.append(_trigger)
async def stop_triggers(self) -> None: async def stop_triggers(self) -> None:
+31 -25
View File
@@ -2,6 +2,7 @@ from cpu_governor_auto_adjust.trigger import Trigger
from cpu_governor_auto_adjust.config import Config from cpu_governor_auto_adjust.config import Config
from functools import cached_property from functools import cached_property
from os import getloadavg from os import getloadavg
import asyncio
class CpuLoadTrigger(Trigger): class CpuLoadTrigger(Trigger):
@@ -54,29 +55,34 @@ class CpuLoadTrigger(Trigger):
def current_load_average_over_under_threshold(self) -> bool: def current_load_average_over_under_threshold(self) -> bool:
return any(load <= threshold for load, threshold in zip(self.current_load, self.low_threshold)) return any(load <= threshold for load, threshold in zip(self.current_load, self.low_threshold))
def run(self) -> None: async def check_load(self) -> None:
current_active = self.active while True:
new_high_load_active = self.current_load_average_over_high_threshold current_active = self.active
new_low_load_active = self.current_load_average_over_under_threshold new_high_load_active = self.current_load_average_over_high_threshold
new_low_load_active = self.current_load_average_over_under_threshold
if not current_active and new_high_load_active:
self.log.info(
"activating trigger, load: %s, high threshold: %s, governor: %s",
self.current_load, self.high_threshold, self.governor.name
)
self.active = True
elif current_active and new_high_load_active: if not current_active and new_high_load_active:
self.log.debug( self.log.info(
"trigger is already active, load: %s, high threshold: %s", "activating trigger, load: %s, high threshold: %s, governor: %s",
self.current_load, self.high_threshold self.current_load, self.high_threshold, self.governor.name
) )
self.active = True
elif current_active and new_low_load_active:
self.log.info( elif current_active and new_high_load_active:
"deactivating trigger, load: %s, low threshold: %s, governor: %s", self.log.debug(
self.current_load, self.low_threshold, self.governor.name "trigger is already active, load: %s, high threshold: %s",
) self.current_load, self.high_threshold
self.active = False )
else:
self.log.debug("trigger is already inactive, load: %s, threshold: %s", self.current_load, self.high_threshold) elif current_active and new_low_load_active:
self.log.info(
"deactivating trigger, load: %s, low threshold: %s, governor: %s",
self.current_load, self.low_threshold, self.governor.name
)
self.active = False
else:
self.log.debug("trigger is already inactive, load: %s, threshold: %s", self.current_load, self.high_threshold)
await asyncio.sleep(1)
async def async_run(self) -> None:
await self.check_load()
@@ -1,12 +1,15 @@
from cpu_governor_auto_adjust.trigger import Trigger from cpu_governor_auto_adjust.trigger import Trigger
from cpu_governor_auto_adjust.config import Config from cpu_governor_auto_adjust.config import Config
import random import random
import asyncio
class TestTrigger1(Trigger): class TestTrigger1(Trigger):
def __init__(self, _config: Config) -> None: def __init__(self, _config: Config) -> None:
super().__init__(_config) super().__init__(_config)
def run(self) -> None: async def async_run(self) -> None:
choices = [False, True] while True:
self.log.debug("run check code of %s", self.__class__.__name__) choices = [False, True]
self.active = random.choice(choices) self.log.debug("run check code of %s", self.__class__.__name__)
self.active = random.choice(choices)
await asyncio.sleep(1)
+14 -8
View File
@@ -1,6 +1,7 @@
from cpu_governor_auto_adjust.trigger import Trigger from cpu_governor_auto_adjust.trigger import Trigger
from cpu_governor_auto_adjust.config import Config from cpu_governor_auto_adjust.config import Config
from datetime import datetime, time from datetime import datetime, time
import asyncio
class TimeTrigger(Trigger): class TimeTrigger(Trigger):
@@ -14,11 +15,16 @@ class TimeTrigger(Trigger):
def end_time(self) -> time: def end_time(self) -> time:
return datetime.strptime(self.config.custom_config['endTime'], '%H:%M').time() return datetime.strptime(self.config.custom_config['endTime'], '%H:%M').time()
def run(self) -> None: async def check_time(self) -> None:
active_current = self.active while True:
active_new = self.start_time() <= datetime.now().time() <= self.end_time() active_current = self.active
if not active_current and active_new: active_new = self.start_time() <= datetime.now().time() <= self.end_time()
self.log.info("activating trigger, start time: %s, end time: %s, governor: %s", self.start_time(), self.end_time(), self.governor.name) if not active_current and active_new:
elif active_current and not active_new: self.log.info("activating trigger, start time: %s, end time: %s, governor: %s", self.start_time(), self.end_time(), self.governor.name)
self.log.info("deactivating trigger, start time: %s, end time: %s, governor: %s", self.start_time(), self.end_time(), self.governor.name) elif active_current and not active_new:
self.active = active_new self.log.info("deactivating trigger, start time: %s, end time: %s, governor: %s", self.start_time(), self.end_time(), self.governor.name)
self.active = active_new
await asyncio.sleep(1)
async def async_run(self) -> None:
await self.check_time()
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "cpu_governor_auto_adjust" name = "cpu_governor_auto_adjust"
version = "0.3.1" version = "0.4.0"
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" }