controller.py 2.54 KB
Newer Older
1 2 3
from __future__ import print_function

import logging
4
from operator import attrgetter
5 6 7 8 9 10 11 12

logger = logging.getLogger('nrm')


class Action(object):

    """Information about a control action."""

13
    def __init__(self, target, command, delta):
14 15
        self.target = target
        self.command = command
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
        self.delta = delta


class ApplicationActuator(object):

    """Actuator in charge of application thread control."""

    def __init__(self, am):
        self.application_manager = am

    def available_actions(self, target):
        ret = []
        for identity, application in \
                self.application_manager.applications.iteritems():
            if target in application.get_allowed_thread_requests():
                delta = application.get_thread_request_impact(target)
                ret.append(Action(application, target, delta))
        return ret
34 35 36 37 38 39 40 41 42 43


class Controller(object):

    """Implements a control loop for resource management."""

    def __init__(self, am, cm, rm):
        self.application_manager = am
        self.container_manager = cm
        self.resource_manager = rm
44
        self.app_actuator = ApplicationActuator(am)
45 46 47 48

    def planify(self, target, machineinfo):
        """Plan the next action for the control loop."""
        total_power = machineinfo['energy']['power']['total']
49
        direction = None
50
        if total_power < target:
51
            direction = 'i'
52
        elif total_power > target:
53 54 55 56 57 58 59 60 61 62
            direction = 'd'

        if direction:
            actions = self.app_actuator.available_actions(direction)
            if actions:
                # TODO: better choice
                actions.sort(key=attrgetter('delta'))
                return actions.pop()
            else:
                return None
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

    def execute(self, action):
        """Build the action for the appropriate manager."""
        assert action
        target_threads = action.target.threads
        update = {'type': 'application',
                  'command': 'threads',
                  'uuid': action.target.uuid,
                  'event': 'threads',
                  }
        if action.command == 'i':
            payload = target_threads['cur'] + 1
        elif action.command == 'd':
            payload = target_threads['cur'] - 1
        else:
            assert False, "impossible command"
        update['payload'] = payload
        return update

    def update(self, action, request):
        """Update tracking across the board to reflect the last action."""
        assert action
        action.target.do_thread_transition(action.command)