Ejemplo n.º 1
0
 def test_calculate_period_end(self):
     period = TimePeriod(1000)
     start_time = self._get_time1()
     period.start_period(start_time)
     period_end = period.calculate_period_end()
     expected_end_time = start_time + timedelta(seconds=1000)
     assert period_end == expected_end_time
Ejemplo n.º 2
0
 def test_calculate_period_end(self):
     period = TimePeriod(1000)
     start_time = self._get_time1()
     period.start_period(start_time)
     period_end = period.calculate_period_end()
     expected_end_time = start_time + timedelta(seconds=1000)
     assert period_end == expected_end_time
Ejemplo n.º 3
0
 def test_calculate_period_end_with_unstarted_period(self):
     with pytest.raises(ValueError):
         period = TimePeriod(1000)
         period_end = period.calculate_period_end()
         assert period_end is None
Ejemplo n.º 4
0
 def test_calculate_period_end_with_unstarted_period(self):
     with pytest.raises(ValueError):
         period = TimePeriod(1000)
         period_end = period.calculate_period_end()
         assert period_end is None
Ejemplo n.º 5
0
class ScalingPolicyInstance:

    _latest_metric_update = None

    state = None
    policy = None
    instance_uuid = None
    threshold_period = None

    def __init__(self, instance_uuid, policy):
        self._logger = logging.getLogger(__name__)
        self.state = ScalingStateUntriggered()
        threshold_period_in_seconds = policy.get_threshold_period_in_seconds()
        self._logger.debug("threshold period of policy %s is %d", policy, threshold_period_in_seconds)
        self.threshold_period = TimePeriod(threshold_period_in_seconds)
        self._latest_metric_update = None
        self.instance_uuid = instance_uuid
        self.policy = policy

    def update_policy_state_and_get_scaling_actions(self, metrics_message):
        scaling_actions = []

        for metric_value in metrics_message.metric_values:
            value = metric_value.value
            timestamp = dateutil.parser.parse(metric_value.timestamp)

            if not self._is_new_metric(timestamp):
                self._logger.debug("metric value %s is outdated for instance %s", repr(metric_value), self.instance_uuid)
                continue

            if self.policy.cooldown_period.is_in_period(timestamp):
                self._logger.debug("metric value %s ignored because of cooldown is active", repr(metric_value))
                continue

            predicate_satisfied = self.policy.value_exceeds_or_undercuts_threshold(float(value))
            self._logger.debug("metric value %s is %s under/over threshold",
                               repr(metric_value),
                               "" if predicate_satisfied else "not"
                               )

            cooldown_start_time = timestamp
            if self.threshold_period.period_started:
                cooldown_start_time = self.threshold_period.calculate_period_end()

            action_required = self.state.update_and_report_if_action_required(
                self,
                predicate_satisfied,
                timestamp,
                metrics_message.uuid
            )

            if action_required:
                scaling_action = self.policy.create_scaling_action(metrics_message.metric_name, self.instance_uuid)
                self.policy.cooldown_period.start_period(cooldown_start_time)
                scaling_actions.append(scaling_action)
                self._logger.info("Triggered scaling action %s, beginning cooldown", repr(scaling_action))

        return scaling_actions

    def _is_new_metric(self, timestamp):
        if self._latest_metric_update is None:
            self._latest_metric_update = timestamp
            return True

        new_metric = timestamp > self._latest_metric_update
        if new_metric:
            self._latest_metric_update = timestamp
        return new_metric

    def __repr__(self):
        return "ScalingPolicyInstance(instance_uuid={},state={},threshold_period={},policy={})".format(
            self.instance_uuid,
            repr(self.state),
            repr(self.threshold_period),
            self.policy.policy_name
        )
Ejemplo n.º 6
0
class ScalingPolicyInstance:

    _latest_metric_update = None

    state = None
    policy = None
    instance_uuid = None
    threshold_period = None

    def __init__(self, instance_uuid, policy):
        self._logger = logging.getLogger(__name__)
        self.state = ScalingStateUntriggered()
        threshold_period_in_seconds = policy.get_threshold_period_in_seconds()
        self._logger.debug("threshold period of policy %s is %d", policy,
                           threshold_period_in_seconds)
        self.threshold_period = TimePeriod(threshold_period_in_seconds)
        self._latest_metric_update = None
        self.instance_uuid = instance_uuid
        self.policy = policy

    def update_policy_state_and_get_scaling_actions(self, metrics_message):
        scaling_actions = []

        for metric_value in metrics_message.metric_values:
            value = metric_value.value
            timestamp = dateutil.parser.parse(metric_value.timestamp)

            if not self._is_new_metric(timestamp):
                self._logger.debug(
                    "metric value %s is outdated for instance %s",
                    repr(metric_value), self.instance_uuid)
                continue

            if self.policy.cooldown_period.is_in_period(timestamp):
                self._logger.debug(
                    "metric value %s ignored because of cooldown is active",
                    repr(metric_value))
                continue

            predicate_satisfied = self.policy.value_exceeds_or_undercuts_threshold(
                float(value))
            self._logger.debug("metric value %s is %s under/over threshold",
                               repr(metric_value),
                               "" if predicate_satisfied else "not")

            cooldown_start_time = timestamp
            if self.threshold_period.period_started:
                cooldown_start_time = self.threshold_period.calculate_period_end(
                )

            action_required = self.state.update_and_report_if_action_required(
                self, predicate_satisfied, timestamp, metrics_message.uuid)

            if action_required:
                scaling_action = self.policy.create_scaling_action(
                    metrics_message.metric_name, self.instance_uuid)
                self.policy.cooldown_period.start_period(cooldown_start_time)
                scaling_actions.append(scaling_action)
                self._logger.info(
                    "Triggered scaling action %s, beginning cooldown",
                    repr(scaling_action))

        return scaling_actions

    def _is_new_metric(self, timestamp):
        if self._latest_metric_update is None:
            self._latest_metric_update = timestamp
            return True

        new_metric = timestamp > self._latest_metric_update
        if new_metric:
            self._latest_metric_update = timestamp
        return new_metric

    def __repr__(self):
        return "ScalingPolicyInstance(instance_uuid={},state={},threshold_period={},policy={})".format(
            self.instance_uuid, repr(self.state), repr(self.threshold_period),
            self.policy.policy_name)