units.manager: devices claiming priority, creating units
This commit is contained in:
parent
6d48f2099d
commit
bc55810995
8 changed files with 95 additions and 45 deletions
|
|
@ -38,9 +38,11 @@ class Application(object):
|
|||
storage_provider = storage.PickleProvider()
|
||||
storage_factory = storage.Factory(storage_provider)
|
||||
|
||||
unit_factory = units.Factory()
|
||||
device_matcher = units.DeviceMatcher()
|
||||
monitors_repository = monitors.Repository()
|
||||
plugins_repository = plugins.Repository(storage_factory, monitors_repository)
|
||||
unit_manager = units.Manager(plugins_repository, monitors_repository)
|
||||
unit_manager = units.Manager(plugins_repository, monitors_repository, unit_factory, device_matcher)
|
||||
|
||||
profile_factory = profiles.Factory()
|
||||
profile_merger = profiles.Merger()
|
||||
|
|
|
|||
|
|
@ -45,9 +45,7 @@ class Daemon(object):
|
|||
if self._profile is None:
|
||||
raise Exception("Cannot start the daemon without setting a profile.")
|
||||
|
||||
for unit_info in self._profile.units:
|
||||
self._unit_manager.create(unit_info.name, unit_info.plugin, unit_info.options)
|
||||
|
||||
self._unit_manager.create(self._profile.units)
|
||||
self.save_active_profile()
|
||||
|
||||
self._unit_manager.plugins_repository.do_static_tuning()
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ class Plugin(object):
|
|||
def dynamic_tuning(self):
|
||||
return self._dynamic_tuning
|
||||
|
||||
@property
|
||||
def devices(self):
|
||||
return self._devices
|
||||
|
||||
def _autoregister_commands(self):
|
||||
"""
|
||||
Register all commands marked using @command_set and @command_get decorators.
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@ class Unit(object):
|
|||
Unit description.
|
||||
"""
|
||||
|
||||
__slots__ = [ "_name", "_type", "_enabled", "_replace", "_options" ]
|
||||
__slots__ = [ "_name", "_type", "_enabled", "_replace", "_devices", "_options" ]
|
||||
|
||||
def __init__(self, name, config):
|
||||
self._name = name
|
||||
self._type = config.pop("type", self._name)
|
||||
self._enabled = config.pop("enabled", True) in [True, "true", 1]
|
||||
self._replace = config.pop("replace", False) in [True, "true", 1]
|
||||
self._devices = config.pop("devices", "*")
|
||||
self._options = dict(config)
|
||||
|
||||
@property
|
||||
|
|
@ -32,6 +33,10 @@ class Unit(object):
|
|||
def replace(self):
|
||||
return self._replace
|
||||
|
||||
@property
|
||||
def devices(self):
|
||||
return self._devices
|
||||
|
||||
@property
|
||||
def options(self):
|
||||
return self._options
|
||||
|
|
|
|||
|
|
@ -1 +1,4 @@
|
|||
from manager import *
|
||||
from device_matcher import *
|
||||
from factory import *
|
||||
from unit import *
|
||||
|
|
|
|||
5
tuned/units/factory.py
Normal file
5
tuned/units/factory.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import tuned.units.unit
|
||||
|
||||
class Factory(object):
|
||||
def create(self, name, type, plugin):
|
||||
return tuned.units.unit.Unit(name, type, plugin)
|
||||
|
|
@ -12,17 +12,19 @@ class Manager(object):
|
|||
Manager instantiates Unit objects, and keeps track of them.
|
||||
"""
|
||||
|
||||
__slots__ = ["_units", "_plugins_repository", "_monitors_repository"]
|
||||
__slots__ = ["_units", "_plugins_repository", "_monitors_repository", "_unit_factory", "_device_matcher"]
|
||||
|
||||
def __init__(self, plugins_repository, monitors_repository):
|
||||
def __init__(self, plugins_repository, monitors_repository, unit_factory, device_matcher):
|
||||
super(self.__class__, self).__init__()
|
||||
self._units = set()
|
||||
self._plugins_repository = plugins_repository
|
||||
self._monitors_repository = monitors_repository
|
||||
self._plugins_repository = plugins_repository
|
||||
self._unit_factory = unit_factory
|
||||
self._device_matcher = device_matcher
|
||||
|
||||
@property
|
||||
def units(self):
|
||||
return self._units.copy()
|
||||
return self._units
|
||||
|
||||
@property
|
||||
def plugins_repository(self):
|
||||
|
|
@ -32,22 +34,65 @@ class Manager(object):
|
|||
def monitors_repository(self):
|
||||
return self._monitors_repository
|
||||
|
||||
def create(self, name, plugin_name, config):
|
||||
log.info("creating unit '%s'" % name)
|
||||
try:
|
||||
new_unit = tuned.units.unit.Unit(self._plugins_repository, self._monitors_repository, name, plugin_name, config)
|
||||
self._units.add(new_unit)
|
||||
return new_unit
|
||||
except tuned.exceptions.TunedException as e:
|
||||
e.log()
|
||||
log.error("unable to create unit '%s'" % name)
|
||||
def create(self, units):
|
||||
# reverse order, newer units have priority to claim a device
|
||||
for unit_info in reversed(units):
|
||||
if not unit_info.enabled:
|
||||
log.debug("skipping disabled unit '%s'" % unit_info.name)
|
||||
continue
|
||||
|
||||
if not self._plugins_repository.is_supported(unit_info.type):
|
||||
log.info("skipping unit '%s', plugin not supported on your system" % unit_info.type)
|
||||
continue
|
||||
|
||||
devices = self._possible_devices(unit_info)
|
||||
if devices is None:
|
||||
continue
|
||||
|
||||
log.info("creating unit '%s' (devices: %s)" % (unit_info.name, ", ".join(devices)))
|
||||
try:
|
||||
self._create_unit(unit_info, devices)
|
||||
except tuned.exceptions.TunedException as e:
|
||||
log.error("unable to create unit '%s' (trace follows)" % unit_info.name)
|
||||
e.log()
|
||||
except Exception as E:
|
||||
log.error("unable to create unit '%s' (%s)" % (unit_info.name, str(e)))
|
||||
|
||||
def _possible_devices(self, unit_info):
|
||||
tunable_devices = self._plugins_repository.tunable_devices(unit_info.type)
|
||||
if len(tunable_devices) == 0:
|
||||
log.info("skipping unit '%s', no devices available" % unit_info.name)
|
||||
return None
|
||||
|
||||
available_devices = [dev for dev in tunable_devices if dev not in self._seized_devices(unit_info.type)]
|
||||
if len(available_devices) == 0:
|
||||
log.info("skipping unit '%s', all devices are already claimed by another unit" % unit_info.name)
|
||||
return None
|
||||
|
||||
devices = self._device_matcher.match_list(unit_info.devices, available_devices)
|
||||
if len(devices) == 0:
|
||||
log.info("skipping unit '%s', no matching devices available" % unit_info.name)
|
||||
return None
|
||||
|
||||
return devices
|
||||
|
||||
def _seized_devices(self, type):
|
||||
devices = []
|
||||
for unit in self._units:
|
||||
if unit.type == type:
|
||||
devices.extend(unit.devices)
|
||||
return set(devices)
|
||||
|
||||
def _create_unit(self, unit_info, devices):
|
||||
plugin = self._plugins_repository.create(unit_info.type, devices, unit_info.options)
|
||||
unit = self._unit_factory.create(unit_info.name, unit_info.type, plugin)
|
||||
self._units.add(unit)
|
||||
|
||||
def delete(self, unit):
|
||||
assert type(unit) is tuned.units.unit.Unit
|
||||
unit.clean()
|
||||
self._plugins_repository.delete(unit.plugin)
|
||||
self._units.delete(unit)
|
||||
|
||||
def delete_all(self):
|
||||
for unit in self._units:
|
||||
unit.clean()
|
||||
self._plugins_repository.delete(unit.plugin)
|
||||
self._units.clear()
|
||||
|
|
|
|||
|
|
@ -9,37 +9,25 @@ class Unit(object):
|
|||
device.
|
||||
"""
|
||||
|
||||
__slots__ = ["_name", "_plugin", "_plugin_repository", "_monitor_repository"]
|
||||
__slots__ = ["_name", "_type", "_plugin"]
|
||||
|
||||
def __init__(self, plugin_repository, monitor_repository, name, plugin_name, config):
|
||||
self._plugin_repository = plugin_repository
|
||||
self._monitor_repository = monitor_repository
|
||||
def __init__(self, name, type, plugin):
|
||||
self._name = name
|
||||
|
||||
(devices, options) = self._get_plugin_params(config)
|
||||
self._plugin = self._plugin_repository.create(plugin_name, devices, options)
|
||||
self._type = type
|
||||
self._plugin = plugin
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def devices(self):
|
||||
return self._plugin.devices
|
||||
|
||||
@property
|
||||
def plugin(self):
|
||||
return self._plugin
|
||||
|
||||
def clean(self):
|
||||
self._plugin_repository.delete(self._plugin)
|
||||
self._plugin = None
|
||||
|
||||
def _get_plugin_params(self, config):
|
||||
if config is None:
|
||||
return (None, {})
|
||||
|
||||
devices = None
|
||||
if "devices" in config:
|
||||
devices = config["devices"]
|
||||
if devices and len(devices) == 0:
|
||||
devices = None
|
||||
del(config["devices"])
|
||||
|
||||
return (devices, config)
|
||||
|
|
|
|||
Loading…
Reference in a new issue