1
0
Fork 0

units.manager: devices claiming priority, creating units

This commit is contained in:
Jan Vcelak 2012-10-26 17:58:03 +02:00
parent 6d48f2099d
commit bc55810995
8 changed files with 95 additions and 45 deletions

View file

@ -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()

View file

@ -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()

View file

@ -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.

View file

@ -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

View file

@ -1 +1,4 @@
from manager import *
from device_matcher import *
from factory import *
from unit import *

5
tuned/units/factory.py Normal file
View 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)

View file

@ -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()

View file

@ -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)