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

import logging
Valentin Reis's avatar
Valentin Reis committed
4
import time
5 6

logger = logging.getLogger('nrm')
Valentin Reis's avatar
Valentin Reis committed
7
logger_power = logging.getLogger('power')
8 9 10 11 12

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
        self.delta = delta

18 19 20 21 22 23 24 25 26 27 28
class PowerActuator(object):

    """Actuator in charge of power control."""

    def __init__(self, sm):
        self.sensor_manager = sm

    def available_actions(self, target):
        actions = []
        pl = self.sensor_manager.get_powerlimits()
        logger.info("power limits: %r:", pl)
29 30
        if target == 'i':
            for k in pl:
31
                r = range(int(pl[k]['curW'])+1, int(pl[k]['maxW']))
32 33 34
                actions.extend([Action(k, s, s - r[0]) for s in r])
        elif target == 'd':
            for k in pl:
35 36
                r = range(1, int(pl[k]['curW']))
                actions.extend([Action(k, s, r[-1] - s) for s in r])
37 38 39
        return actions

    def execute(self, action):
Valentin Reis's avatar
Valentin Reis committed
40 41 42 43
        logger.info("changing power limit. command: %r, delta: %r, target: %r",
                    action.command, action.delta, action.target)
        # sensor_manager is a SensorManager, which is not only about sensing
        # but also about setting power limits.
44
        # self.sensor_manager.set_powerlimit(action.target, action.command)
45 46 47 48

    def update(self, action):
        pass

49 50 51 52 53

class Controller(object):

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

54 55
    def __init__(self, actuators):
        self.actuators = actuators
56 57 58

    def planify(self, target, machineinfo):
        """Plan the next action for the control loop."""
Valentin Reis's avatar
Valentin Reis committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
        # current_e = float(machineinfo['energy']['energy']['cumulative']['package-0'])/(1000*1000) # in joules
        current_p = float(machineinfo['energy']['power']['p0'])/(1000*1000) # in joules
        current_p = float(machineinfo['energy']['power']['p1'])/(1000*1000) # in joules
        logger_power.info("%s %s %s" % (time.time(),current_p,current_p))
        return (None,None)

        # direction = None
        # if total_power < target:
            # direction = 'i'
        # elif total_power > target:
            # direction = 'd'

        # if direction:
            # actions = []
            # for act in self.actuators:
                # newactions = act.available_actions(direction)
                # actions.extend([(a, act) for a in newactions])
            # if actions:
                # # TODO: better choice
                # actions.sort(key=lambda x: x[0].delta)
                # return actions.pop(0)
            # else:
                # return (None, None)
82

83
    def execute(self, action, actuator):
84
        """Build the action for the appropriate manager."""
85
        actuator.execute(action)
86

87
    def update(self, action, actuator):
88
        """Update tracking across the board to reflect the last action."""
89
        actuator.update(action)
90 91 92 93

    def run_policy(self, containers):
        """Run policies on containers with policies set."""
        for container in containers:
94
            pp = containers[container].power
95 96 97 98 99 100 101 102 103 104 105 106
            if pp['policy']:
                apps = self.actuators[0].application_manager.applications
                if apps:
                    app = next(apps[a] for a in apps if apps[a].container_uuid
                               == container)
                    ids = containers[container].resources['cpus']
                    # Run policy only if all phase contexts have been received
                    if not filter(lambda i: not app.phase_contexts[i]['set'],
                                  ids):
                        pp['manager'].run_policy(app.phase_contexts)
                        if filter(lambda i: app.phase_contexts[i]['set'], ids):
                            logger.debug("Phase context not reset %r", app)