示例#1
0
 def __init__(self, interval):
     """
     Set up the ticker
     """
     self.interval = interval
     self.subscriptions = {}
     # set up a twisted asynchronous repeat call
     self.task = ExtendedLoopingCall(self._callback)
示例#2
0
class Ticker(object):
    """
    Represents a repeatedly running task that calls
    hooks repeatedly. Overload _callback to change the
    way it operates.
    """

    @inlineCallbacks
    def _callback(self):
        """
        This will be called repeatedly every self.interval seconds.
        self.subscriptions contain tuples of (obj, args, kwargs) for
        each subscribing object.

        If overloading, this callback is expected to handle all
        subscriptions when it is triggered. It should not return
        anything and should not traceback on poorly designed hooks.
        The callback should ideally work under @inlineCallbacks so it can yield
        appropriately.
        """
        for key, (obj, args, kwargs) in self.subscriptions.items():
            hook_key = yield kwargs.get("hook_key", "at_tick")
            if not obj:
                # object was deleted between calls
                self.validate()
                continue
            try:
                yield _GA(obj, hook_key)(*args, **kwargs)
            except Exception:
                log_trace()

    def __init__(self, interval):
        """
        Set up the ticker
        """
        self.interval = interval
        self.subscriptions = {}
        # set up a twisted asynchronous repeat call
        self.task = ExtendedLoopingCall(self._callback)

    def validate(self, start_delay=None):
        """
        Start/stop the task depending on how many
        subscribers we have using it.
        """
        subs = self.subscriptions
        if None in subs.values():
            # clean out objects that may have been deleted
            subs = dict((store_key, obj) for store_key, obj in subs if obj)
            self.subscriptions = subs
        if self.task.running:
            if not subs:
                self.task.stop()
        elif subs:
            #print "starting with start_delay=", start_delay
            self.task.start(self.interval, now=False, start_delay=start_delay)

    def add(self, store_key, obj, *args, **kwargs):
        """
        Sign up a subscriber to this ticker. If kwargs contains
        a keyword _start_delay, this will be used to delay the start
        of the trigger instead of interval.
        """
        start_delay = kwargs.pop("_start_delay", None)
        self.subscriptions[store_key] = (obj, args, kwargs)
        self.validate(start_delay=start_delay)

    def remove(self, store_key):
        """
        Unsubscribe object from this ticker
        """
        self.subscriptions.pop(store_key, False)
        self.validate()

    def stop(self):
        """
        Kill the Task, regardless of subscriptions
        """
        self.subscriptions = {}
        self.validate()