Ejemplo n.º 1
0
 def __init__(self):
     ConfigurableNode.__init__(self)
     self._url = 'unknown'
     self._poll_event = None
     self._period = 0.2
     # Pre-load attributes.
     self.off_text = "Off"
     self.on_text = "On"
     self.auto_text = "Auto"
     self.reverse_output = 0
     self.output = REQUIRED
     self.input = REQUIRED
     self.period = self._period
     self.asyncOK = 1
     self.state = 2
     self.debug = 0
     self.__running = False
     self._init_debug()
     self.OFF = EnumeratedValue(0, self.off_text)
     self.ON = EnumeratedValue(1, self.on_text)
     self.AUTO = EnumeratedValue(2, self.auto_text)
     self._NORMAL = 0
     self._SAFETY = 1
     self._output_state = self._NORMAL
     self._output_lock = Lock()
     self._changes_at = 0
     self._waiting_value = None
     self._value = None
     self._lock = Lock()
     return
Ejemplo n.º 2
0
class SubscriptionExecutioner(object):
    PENDING = EnumeratedValue(0, 'Pending')
    PREPARING = EnumeratedValue(1, 'Preparing for export')
    GETTING = EnumeratedValue(2, 'Getting data')
    FORMATTING = EnumeratedValue(3, 'Formatting data')
    SENDING = EnumeratedValue(4, 'Starting transaction')
    SCHEDULING = EnumeratedValue(5, 'Scheduling next export')
    COMPLETED = EnumeratedValue(6, 'Completed')
    STAGES = [
        PENDING, PREPARING, GETTING, FORMATTING, SENDING, SCHEDULING, COMPLETED
    ]

    def __init__(self, group, subscription):
        self.group = group
        self.subscription = subscription
        self.stagecallbacks = [(self.execute_prepare, ),
                               (self.execute_get_data, ),
                               (self.execute_format_data, ),
                               (self.execute_start_transaction, ),
                               (self.execute_schedule_export, )]
        self.stagearguments = ()

    def get_stage(self):
        return self.STAGES[-len(self.stagecallbacks) - 1]

    def execute(self):
        stage = self.get_stage()
        stagemethods = self.stagecallbacks.pop(0)
        try:
            for stagemethod in stagemethods:
                stagearguments = self.stagearguments
                result = stagemethod(*stagearguments)
                self.stagearguments = (result, )
        except Exception, error:
            self.subscription.handle_export_exception(error, stage)
            if not self.is_complete():
                self.group.notify_stage_aborted(self, stage)
            else:
                self.group.notify_executioner_aborted(self)
            self.stagecallbacks, self.stagearguments = [], ()
        else:
Ejemplo n.º 3
0
class Calculated(_Trigger, Calculator):
    implements(ITrigger)

    INITIALIZING = EnumeratedValue(0, 'init')
    INACTIVE = EnumeratedValue(1, 'inactive')
    ACTIVE = EnumeratedValue(2, 'active')
    ERROR = EnumeratedValue(3, 'error')
    DISABLED = EnumeratedValue(4, 'disabled')
    STATES = {
        INITIALIZING: {
            'start': INACTIVE,
            'stop': DISABLED
        },
        INACTIVE: {
            'clear': INACTIVE,
            'trigger': ACTIVE,
            'stop': DISABLED
        },
        ACTIVE: {
            'clear': INACTIVE,
            'trigger': ACTIVE,
            'stop': DISABLED
        },
        ERROR: {
            'clear': INACTIVE,
            'trigger': ERROR,
            'stop': DISABLED
        },
        DISABLED: {
            'stop': DISABLED,
            'start': INACTIVE
        }
    }
    ACTIONS = ('clear', 'trigger')
    EVENTTYPES = {
        (ACTIVE, INACTIVE): TriggerCleared,
        (INACTIVE, ACTIVE): TriggerActivated
    }

    def __init__(self, *args):
        _Trigger.__init__(self, *args)
        Calculator.__init__(self)
        self.state = self.INITIALIZING
        self.scheduled = None
        self._running = Flag()
        self._start_failed = False

    def configure(self, config):
        Calculator.configure(self, config)
        _Trigger.configure(self, config)
        message = ''
        if 'poll_period' in config:
            try:
                policy = float(config['poll_period'])
            except ValueError:
                raise ValueError(
                    'Value of field \'Poll period\' is not numeric')
        if not (config.has_key('message') and config['message']):
            for var in self.variables:
                if message:
                    message += ', '
                message += '%s = ${%s}' % (var['vn'], var['vn'])
            set_attribute(self, 'message', message, {})
        else:
            set_attribute(self, 'message', REQUIRED, config)
        set_attribute(self, 'poll_period', 2, config, float)
        set_attribute(self, 'critical_input', '', config)
        set_attribute(self, 'description', '', config)
        set_attribute(self, 'enabled', 1, config, as_boolean)
        self.manager = self.parent

    def configuration(self):
        config = Calculator.configuration(self)
        config.update(_Trigger.configuration(self))
        get_attribute(self, 'message', config)
        get_attribute(self, 'poll_period', config, str)
        get_attribute(self, 'critical_input', config)
        get_attribute(self, 'description', config)
        get_attribute(self, 'enabled', config, str)
        return config

    def is_active(self):
        return self.get_state() is self.ACTIVE

    def is_running(self):
        return self._running.isSet()

    def get_state(self):
        return self.state

    def get(self, skipCache=0):
        return str(self.get_state())

    def start(self):
        if not self._running.isSet():
            _Trigger.start(self)
            variables = []
            self._message = ''
            message = self.message
            while '$' in message:
                index = message.index('$')
                try:
                    if message[index + 1] == '{':
                        end = string.find(message, '}', index)
                        if end > -1:
                            var = message[index:end + 1]
                            variable = var[2:-1]
                            if '$' not in variable and '{' not in variable:
                                message = string.replace(message, var, '%s')
                                variables.append(variable)
                except IndexError:
                    pass
                self._message += message[0:index + 1]
                message = message[index + 1:]
            self._message += message
            self._message_vars = tuple(variables)
            self.state = self.STATES[self.state]['start']
            self._running.set()
        try:
            Calculator.start(self)
        except:
            message = "Failed to start Trigger %r.  Will retry in 30 secs."
            msglog.error(message % self.name)
            if not self._start_failed:
                msglog.exception(prefix="handled")
            self._start_failed = True
        else:
            message = "Trigger %r started.  Evaluation runs in 30 seconds."
            msglog.inform(message % self.name)
            self._start_failed = False
        finally:
            self.reschedule(30)

    def stop(self):
        self.synclock.acquire()
        try:
            self._running.clear()
            self.state = self.STATES[self.state]['stop']
        finally:
            self.synclock.release()
        self.reschedule()
        Calculator.stop(self)
        _Trigger.stop(self)

    def __call__(self):
        if not self.started:
            self.start()
        else:
            try:
                self._run_evaluation()
            except:
                msglog.exception()
                msglog.inform('Trigger reschedule delayed 20 seconds.')
                delay = 20
            else:
                delay = self.poll_period
            finally:
                self.reschedule(delay)

    def _run_evaluation(self):
        values = self._get_values(self.local_context)
        current_value = self.evaluate(values)
        self.synclock.acquire()
        try:
            # Check running state before performing evaluation.
            if not self._running.isSet():
                return
            action = self.ACTIONS[current_value]
            previous = self.state
            self.state = current = self.STATES[self.state][action]
        finally:
            self.synclock.release()
        eventtype = self.EVENTTYPES.get((previous, current))
        if not eventtype:
            return
        timestamp = time.time()
        if self.critical_input:
            value = values[self.critical_input]
        elif len(values.keys()) == 1:
            value = values.values()[0]
        else:
            value = None
        event = eventtype(self, timestamp, value, values)
        self._dispatch(event)

    def _dispatch(self, event):
        self.manager.dispatcher.dispatch(event)

    def reschedule(self, delay=None):
        scheduled, self.scheduled = self.scheduled, None
        if scheduled:
            scheduled.cancel()
        if self._running.isSet():
            if delay is None:
                delay = self.poll_period
            self.scheduled = scheduler.after(delay, self.manager.queue_trigger,
                                             (self, ))
        return self.scheduled
Ejemplo n.º 4
0
    def trim_ge(self, column, value):
        pass

    def reset(self):
        pass

    def destroy(self):
        pass


##
# Type Conversion data and functions.
#
_types = {
    'char': EnumeratedValue(0, 'c'),
    'char': EnumeratedValue(1, 'b'),
    'unsigned_char': EnumeratedValue(2, 'B'),
    'short': EnumeratedValue(3, 'h'),
    'unsgined_short': EnumeratedValue(4, 'H'),
    'int': EnumeratedValue(5, 'i'),
    'unsigned_int': EnumeratedValue(6, 'I'),
    'long': EnumeratedValue(7, 'l'),
    'unsigned_long': EnumeratedValue(8, 'L'),
    'float': EnumeratedValue(9, 'f'),
    'double': EnumeratedValue(10, 'd')
}


def _to_type_value(name):
    return _types[name]
Ejemplo n.º 5
0
 def test_1(self):
     try:
         ed = EnumeratedDictionary()
     except:
         raise 'Failed to create empty dictionary'
     try:
         one = EnumeratedValue(1, 'one')
         two = EnumeratedValue(2, 'two')
         ed[1] = one
         ed['two'] = two
     except:
         raise 'Basic assignment failed'
     try:
         ed[3] = one
     except:
         pass
     else:
         raise 'Failed to detect mismatch between int key and value'
     try:
         ed['three'] = one
     except:
         pass
     else:
         raise 'Failed to detect mismatch between str key and value'
     try:
         s = str(ed)
     except:
         raise 'Failed to produce str from self'
     #exp_str = "{1: EnumeratedValue(1,'one'), 2: EnumeratedValue(2,'two')}"
     exp_str = "{1: {'__base__': 'EnumeratedValue', 'num': 1, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'one'}, 2: {'__base__': 'EnumeratedValue', 'num': 2, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'two'}}"
     if s != exp_str:
         raise 'str conversion failed (%s vs %s)' % (s, exp_str)
     try:
         r = repr(ed)
     except:
         raise 'Failed to produce repr string'
     #exp_repr = "EnumeratedDictionary({1: EnumeratedValue(1,'one'), 2: EnumeratedValue(2,'two')})"
     exp_repr = "EnumeratedDictionary({1: {'__base__': 'EnumeratedValue', 'num': 1, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'one'}, 2: {'__base__': 'EnumeratedValue', 'num': 2, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'two'}})"
     if r != exp_repr:
         raise 'repr string comparison failed (%s vs %s)' % (r, exp_repr)
     if ed[1] != one:
         raise 'Failed to get correct item for int key'
     if ed['two'] != two:
         raise 'Failed to get correct item for str key'
     try:
         ed['three']
     except:
         pass
     else:
         raise 'Failed to raise key exception on bad key'
     if ed.items() != [(1, EnumeratedValue(1,'one')), (2, EnumeratedValue(2,'two'))]:
         raise 'Failed to produce items'
     try:
         ed[3]='three'
         ed['four']=4
     except:
         raise 'Failed set for simple int and str items'
     if ed[3] != EnumeratedValue(3,'three'):
         raise 'Implicit creation of EnumeratedValue failed'
     if ed['three'] != EnumeratedValue(3,'three'):
         raise 'str dict did not get implicit assignment'
     ed2 = EnumeratedDictionary(ed)
     try:
         if ed == ed2:
             pass
         else:
             raise 'Equality test failed'
     except:
         raise 'Equality test crashed'
     ed2 = EnumeratedDictionary(ed)
     try:
         ed3 = EnumeratedDictionary(ed2)
     except:
         raise 'Failed to instanciate from another EnumeratedDictionary'
     if ed != ed3:
         raise 'Non-equality test failed'
     try:
         del ed2[1]
     except:
         raise 'del failed'
     if ed2.get(1) != None:
         raise 'Failed to del an item'
     if ed2.get('one') != None:
         raise 'Failed to del an item from str_dict'
     try:
         del ed2['two']
     except:
         raise 'del failed'
     if ed2.get(2) != None:
         raise 'Failed to del an item'
     if ed2.get('two') != None:
         raise 'Failed to del an item from str_dict'
     s = str(ed)
     #exp_str = "{1: EnumeratedValue(1,'one'), 2: EnumeratedValue(2,'two'), 3: EnumeratedValue(3,'three'), 4: EnumeratedValue(4,'four')}"
     exp_str = "{1: {'__base__': 'EnumeratedValue', 'num': 1, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'one'}, 2: {'__base__': 'EnumeratedValue', 'num': 2, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'two'}, 3: {'__base__': 'EnumeratedValue', 'num': 3, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'three'}, 4: {'__base__': 'EnumeratedValue', 'num': 4, '__class__': 'mpx.lib.EnumeratedValue', 'str': 'four'}}"
     if s != exp_str:
         raise 'Failed to survive all the stuff I tried to do to it.... (%s vs %s)' % (s, exp_str)
Ejemplo n.º 6
0
class CalculatedTrigger(Calculator, EventProducerMixin):
    INITIALIZING = EnumeratedValue(0, 'init')
    INACTIVE = EnumeratedValue(1, 'inactive')
    TRIGGERED = EnumeratedValue(2, 'triggered')
    SENDING = EnumeratedValue(3, 'sending')
    SENT = EnumeratedValue(4, 'sent')
    ACKNOWLEDGED = EnumeratedValue(5, 'acknowledged')
    ERROR = EnumeratedValue(6, 'error')
    DISABLED = EnumeratedValue(7, 'disabled')
    STATE = {
        INITIALIZING: {
            'start': INACTIVE,
            'stop': DISABLED
        },
        INACTIVE: {
            'start': INACTIVE,
            'clear': INACTIVE,
            'trigger': TRIGGERED,
            'stop': DISABLED
        },
        TRIGGERED: {
            'start': ERROR,
            'caught': SENDING,
            'stop': DISABLED
        },
        SENDING: {
            'start': ERROR,
            'succeed': SENT,
            'fail': ERROR,
            'stop': DISABLED
        },
        SENT: {
            'start': SENT,
            'clear': INACTIVE,
            'trigger': SENT,
            'acknowledge': ACKNOWLEDGED,
            'stop': DISABLED
        },
        ACKNOWLEDGED: {
            'start': ACKNOWLEDGED,
            'clear': INACTIVE,
            'trigger': ACKNOWLEDGED,
            'acknowledge': ACKNOWLEDGED,
            'stop': DISABLED
        },
        ERROR: {
            'start': ERROR,
            'clear': INACTIVE,
            'trigger': ERROR,
            'stop': DISABLED
        },
        DISABLED: {
            'start': INACTIVE,
            'stop': DISABLED
        }
    }

    def __init__(self):
        Calculator.__init__(self)
        EventProducerMixin.__init__(self)
        self._state = self.INITIALIZING
        self._current_id = None
        self._scheduled = None
        self._state_lock = Lock()
        self._schedule_lock = Lock()
        self.require_acknowledge = 0
        return

    def get(self, skipCache=0):
        return int(self._state)

    def __str__(self):
        return '%s: %s' % (self.name, str(self._state))

    def configure(self, config):
        Calculator.configure(self, config)
        message = ''
        if not (config.has_key('message') and config['message']):
            for var in self.variables:
                if message:
                    message += ', '
                message += '%s = ${%s}' % (var['vn'], var['vn'])
            set_attribute(self, 'message', message, {})
        else:
            set_attribute(self, 'message', REQUIRED, config)
        set_attribute(self, 'poll_period', 0.1, config, float)
        set_attribute(self, 'critical_input', '', config)
        set_attribute(self, 'send_retries', 3, config, int)
        set_attribute(self, 'enabled', 1, config, as_boolean)
        set_attribute(self, 'require_acknowledge', 0, config, as_boolean)
        self._manager = self.parent.parent

    def configuration(self):
        config = Calculator.configuration(self)
        get_attribute(self, 'message', config)
        get_attribute(self, 'poll_period', config, str)
        get_attribute(self, 'critical_input', config)
        get_attribute(self, 'send_retries', config)
        get_attribute(self, 'enabled', config, str)
        return config

    def enable(self):
        self.enabled = 1
        self.start()

    def disable(self):
        self.enabled = 0
        self.stop()

    def is_enabled(self):
        return self.enabled

    def get_state_name(self):
        return str(self._state)

    def start(self):
        self.STATE = {}
        self.STATE.update(self.__class__.STATE)
        if self.require_acknowledge:
            self.STATE[self.__class__.SENT]['clear'] = self.__class__.SENT
        Calculator.start(self)
        variables = []
        self._message = ''
        message = self.message
        while '$' in message:
            index = message.index('$')
            try:
                if message[index + 1] == '{':
                    end = string.find(message, '}', index)
                    if end > -1:
                        var = message[index:end + 1]
                        variable = var[2:-1]
                        if '$' not in variable and '{' not in variable:
                            message = string.replace(message, var, '%s')
                            variables.append(variable)
            except IndexError:
                pass
            self._message += message[0:index + 1]
            message = message[index + 1:]
        self._message += message
        self._message_vars = tuple(variables)
        self._change_state('start')

    def stop(self):
        # this is where we need to cancel our schedule entry.
        self._change_state('stop')
        Calculator.stop(self)

    def caught(self, alarm):
        if alarm.__class__ == AlarmTriggerEvent:
            self._caught_trigger(alarm)
        elif alarm.__class__ == AlarmClearEvent:
            self._caught_clear(alarm)

    def success(self, alarm):
        self._change_state('succeed')

    def fail(self, alarm):
        msglog.log('broadway', msglog.types.WARN,
                   'Failed sending alarm -> %s' % alarm)
        self._change_state('fail')

    ##
    # @todo Consider creating and using an alarm ack event
    #       similar to the way that trigger and clear are used.
    #       This would allow the manager to keep a list of
    #       'active' 'unacknowledged' alarms so that something
    #       like the alarm handler could generate a list.
    def acknowledge(self, alarm=None):
        self._change_state('acknowledge')

    def state(self, alarm):
        return self._state

    def check_condition(self):
        try:
            values = self._get_values(self.local_context)
        except:
            msglog.exception()
            self._reschedule()
            return
        value = None
        if self.critical_input:
            value = values[self.critical_input]
        elif len(values.keys()) == 1:
            value = values.values()[0]
        if self._evaluate(values):
            self._trigger(time.time(), value, values)
        else:
            self._clear(time.time(), value, values)

    def _reschedule(self):
        self._schedule_lock.acquire()
        try:
            if (self._scheduled is None or self._scheduled.executing()
                    or self._scheduled.expired()):
                self._scheduled = scheduler.after(
                    self.poll_period, self._manager.queue_alarm_check,
                    (self, ))
        finally:
            self._schedule_lock.release()
        return

    def _have_trasition(self, action):
        self._state_lock.acquire()
        try:
            actions = self.STATE[self._state]
            return actions.has_key(action)
        finally:
            self._state_lock.release()
        raise EUnreachableCode()

    def _change_state(self, action):
        self._state_lock.acquire()
        try:
            actions = self.STATE[self._state]
            if not actions.has_key(action):
                raise EInvalidValue(
                    'action', action,
                    'Invalid action from state %s' % self._state)
            state = actions[action]
            if self.TRANSITION[state]:
                self.TRANSITION[state](self)
            self._state = state
        finally:
            self._state_lock.release()
        return

    ##
    # @todo May want to add another state that waits for the
    #       AlarmClearEvent to be confirmed caught, but then
    #       again, maybe not.
    def _clear(self, timestamp, value, values):
        try:
            self._change_state('clear')
            # If the alarm is currently 'active'
            if (self._state == self.ACKNOWLEDGED or
                (self._state == self.SENT and not self.require_acknowledge)):
                if self._current_id != None:
                    clear = AlarmClearEvent(self, self._current_id, timestamp,
                                            value, values)
                    self._current_id = None
                    self.event_generate(clear)
                else:
                    msglog.log('broadway', msglog.types.WARN,
                               'IGNORING CLEAR BECAUSE NO CURRENT ID')
        except EInvalidValue:
            pass

    def _trigger(self, timestamp, value, values):
        try:
            state = self._state
            self._change_state('trigger')
            if state == self.INACTIVE:
                self._current_id = self._manager.unique_id()
                message = self._message
                for var in self._message_vars:
                    if values.has_key(var):
                        message = string.replace(message, '%s',
                                                 str(values[var]), 1)
                    else:
                        message = string.replace(message, '%s', '${%s}' % var,
                                                 1)
                trigger = AlarmTriggerEvent(self, self._current_id, timestamp,
                                            value, values, message)
                self.event_generate(trigger)
        except EInvalidValue:
            pass

    def _caught_trigger(self, alarm):
        self._change_state('caught')

    def _caught_clear(self, alarm):
        pass

    TRANSITION = {
        INACTIVE: _reschedule,
        TRIGGERED: None,
        SENDING: None,
        SENT: _reschedule,
        ACKNOWLEDGED: _reschedule,
        ERROR: _reschedule,
        DISABLED: None
    }
Ejemplo n.º 7
0
 def test_dumps_enumerated_value(self):
     print "\n", 60 * "-"
     print dumps((EnumeratedValue(12, 'twelve'), ))
     print 60 * "-"
Ejemplo n.º 8
0
print dumps((StringClass("Text with ]]>"), ))

print """
#
# The StringMarshaller is more advanced then the built in string marshelling.
# We could remove our escape hack and replace the string marshalling.
#
>>> Marshaller.dispatch[types.StringType] = \\
    Marshaller.dispatch[types.InstanceType]
"""
Marshaller.dispatch[types.StringType] = Marshaller.dispatch[types.InstanceType]
print """
#
# We could do a cleaner reimplementation, but this just show that now the str
# marshaller uses the InstanceType, which I've extended to support registerring
# handlers, blah, blah, blah...
#
>>> print dumps(('this is a test.',)) # Look ma, CDATA goodies!
"""
print dumps(('this is a test.', ))

from mpx.lib import EnumeratedValue

print dumps((EnumeratedValue(2, "asdf"), ))

from mpx.lib.magnitude import MagnitudeInterface

print dumps((MagnitudeInterface(1), ))
print dumps((MagnitudeInterface(2L), ))
print dumps((MagnitudeInterface(3.0), ))