Source code for selinon.strategy

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ######################################################################
# Copyright (C) 2016-2018  Fridolin Pokorny, fridolin.pokorny@gmail.com
# This file is part of Selinon project.
# ######################################################################
"""Strategy for scheduling dispatcher - system state sampling."""

import importlib

from .errors import ConfigurationError
from .helpers import check_conf_keys
from .helpers import get_function_arguments


[docs]class Strategy: """Sampling strategy for Dispatcher.""" _DEFAULT_MODULE = 'selinon.strategies' _DEFAULT_FUNCTION = 'biexponential_increase' _DEFAULT_FUNC_ARGS = {'start_retry': 2, 'max_retry': 120} _EXPECTED_STRATEGY_FUNC_ARGS = {'status'} def __init__(self, module=None, function=None, func_args=None): """Instantiate strategy function representation. :param module: module from which sampling strategy should be imported :param function: sampling function name :param func_args: sampling function arguments """ self.module = module or self._DEFAULT_MODULE self.function = function or self._DEFAULT_FUNCTION self.func_args = func_args or self._DEFAULT_FUNC_ARGS
[docs] @classmethod def from_dict(cls, strategy_dict, flow_name): """Parse strategy entry. :param strategy_dict: strategy entry in config to be parsed :param flow_name: name of the flow for which the strategy function should be used. """ if not strategy_dict: return cls() if not isinstance(strategy_dict, dict): raise ConfigurationError("Strategy not defined properly in global configuration section, expected dict," "got %s in flow %r" % (strategy_dict, flow_name)) if 'name' not in strategy_dict: raise ConfigurationError("Sampling strategy stated in global configuration but no strategy" "name defined in flow %s" % flow_name) if not isinstance(strategy_dict['args'], dict): raise ConfigurationError('Arguments to strategy function should be stated as dict,' 'got %s instead in flow %r' % (strategy_dict['args'], flow_name)) strategy_module = strategy_dict.get('import', cls._DEFAULT_MODULE) raw_module = importlib.import_module(strategy_module) raw_func = getattr(raw_module, strategy_dict['name']) # perform checks on args supplied user_args_keys = strategy_dict['args'].keys() func_args = set(get_function_arguments(raw_func)) if (func_args - user_args_keys) != cls._EXPECTED_STRATEGY_FUNC_ARGS: raise ConfigurationError('Unknown or invalid arguments supplied to sampling strategy function,' 'expected %s, got %s for strategy %r in flow %r' % ((func_args - cls._EXPECTED_STRATEGY_FUNC_ARGS), set(user_args_keys), strategy_dict['name'], flow_name)) unknown_conf = check_conf_keys(strategy_dict, known_conf_opts=('name', 'import', 'args')) if unknown_conf: raise ConfigurationError("Unknown configuration for sampling strategy %r supplied: '%s'" % (strategy_dict['name'], unknown_conf)) return cls(strategy_module, strategy_dict['name'], strategy_dict['args'])