Using a simple, hysteresis based approach… currently in this first version the optimizer recursively moves modules out of a thread until a certain timing target is reached; the "modules moved out" just mentioned are then partitioned into new threads according to their latest time profile. Very simple, but very effective. Todo: Implement merging threads with (again) good behaving workloads.
52 lines
1.4 KiB
Python
52 lines
1.4 KiB
Python
from threading import Thread
|
|
import time
|
|
|
|
from .util import SettingsBase
|
|
from .threads import AutomagicManager
|
|
|
|
__all__ = [
|
|
"Module", "AsyncModule", "IntervalModule",
|
|
]
|
|
|
|
class Module(SettingsBase):
|
|
output = None
|
|
|
|
def registered(self, status_handler):
|
|
"""Called when this module is registered with a status handler"""
|
|
|
|
def inject(self, json):
|
|
if self.output:
|
|
if "name" not in self.output:
|
|
self.output["name"] = self.__name__
|
|
json.insert(0, self.output)
|
|
|
|
class AsyncModule(Module):
|
|
def registered(self, status_handler):
|
|
self.thread = Thread(target=self.mainloop)
|
|
self.thread.daemon = True
|
|
self.thread.start()
|
|
|
|
def mainloop(self):
|
|
"""This is run in a separate daemon-thread"""
|
|
|
|
class IntervalModule(Module):
|
|
interval = 5 # seconds
|
|
managers = {}
|
|
|
|
def registered(self, status_handler):
|
|
if self.interval in IntervalModule.managers:
|
|
IntervalModule.managers[self.interval].add(self)
|
|
else:
|
|
am = AutomagicManager(self.interval)
|
|
am.add(self)
|
|
IntervalModule.managers[self.interval] = am
|
|
|
|
def __call__(self):
|
|
self.run()
|
|
|
|
def run(self):
|
|
"""Called approximately every self.interval seconds
|
|
|
|
Do not rely on this being called from the same thread at all times.
|
|
If you need to always have the same thread context, subclass AsyncModule."""
|