コード例 #1
0
    def __init__(self, initval, readonly=False, setter=None, getter=None, max_discard=100, *args, **kwargs):
        """
        readonly (bool): if True, value setter will raise an exception. It's still
            possible to change the value by calling _set() and then notify()
        setter (callable value -> value): function that will be called whenever the value has to
            be changed and returns the new actual value (which might be different
            from what was given).
        getter (callable value -> value): function that will be called whenever the value has to
            be read and returns the current actual value.
        max_discard (int): amount of updates that can be discarded in a row if
                           a new one is already available. 0 to keep (notify)
                           all the messages (dangerous if callback is slower
                           than the generator).
        """
        VigilantAttributeBase.__init__(self, initval, *args, **kwargs)

        self.readonly = readonly
        if setter is None:
            self._setter = WeakMethod(self.__default_setter)
        else:
            self._setter = WeakMethod(setter) # to avoid cycles

        if getter is not None:
            self._getter = WeakMethod(getter)  # to avoid cycles
        else:
            self._getter = None

        # different from ._listeners for notify() to do different things
        self._remote_listeners = set() # any unique string works

        self._global_name = None # to be filled when registered
        self._ctx = None
        self.pipe = None
        self.debug = False  # If True, this VA will print a call stack when its value is set
        self.max_discard = max_discard
コード例 #2
0
    def subscribe(self, listener):
        with self._lock:
            count_before = self._count_listeners()

            # add string to listeners if listener is string
            if isinstance(listener, basestring):
                self._remote_listeners.add(listener)
            else:
                assert callable(listener)
                self._listeners.add(WeakMethod(listener))

            logging.debug("Listener %r subscribed, now %d subscribers on %s",
                          listener, self._count_listeners(), self._global_name)
            if count_before == 0:
                try:
                    self.start_generate()
                except Exception as ex:
                    logging.error("Subscribing listener %r to the dataflow failed. %s", listener, ex)
                    if isinstance(listener, basestring):
                        # remove string from listeners
                        self._remote_listeners.discard(listener)
                    else:
                        self._listeners.discard(WeakMethod(listener))
                    logging.debug("Listener %r unsubscribed, now %d subscribers on %s", listener,
                                  self._count_listeners(), self._global_name)
                    raise
コード例 #3
0
ファイル: _dataflow.py プロジェクト: effting/odemis
    def subscribe(self, listener):
        """
        Register a callback function to be called when the ActiveValue is
        listener (function): callback function which takes as arguments
           dataflow (this object) and data (the new data array)
        """
        # TODO update rate argument to indicate how often we need an update?
        assert callable(listener)

        with self._lock:
            count_before = len(self._listeners)
            self._listeners.add(WeakMethod(listener))
            logging.debug("Listener %r subscribed, now %d subscribers",
                          listener, len(self._listeners))
            if count_before == 0:
                try:
                    self.start_generate()
                except Exception as ex:
                    logging.error(
                        "Subscribing listener %r to the dataflow failed. %s",
                        listener, ex)
                    self._listeners.discard(WeakMethod(listener))
                    logging.debug(
                        "Listener %r unsubscribed, now %d subscribers",
                        listener, len(self._listeners))
                    raise
コード例 #4
0
    def __init__(self, notifier, uri, max_discard, zmq_ctx):
        """
        notifier (callable): method to call when a new array arrives
        uri (string): unique string to identify the connection
        max_discard (int)
        zmq_ctx (0MQ context): available 0MQ context to use
        """
        threading.Thread.__init__(self, name="zmq for dataflow " + uri)
        self.daemon = True
        self.uri = uri
        self.max_discard = max_discard
        self._ctx = zmq_ctx
        # don't keep strong reference to notifier so that it can be garbage
        # collected normally and it will let us know then that we can stop
        self.w_notifier = WeakMethod(notifier)

        # create a zmq synchronised channel to receive _commands
        self._commands = zmq_ctx.socket(zmq.PAIR)
        self._commands.connect("inproc://" + uri)

        # create a zmq subscription to receive the data
        self._data = zmq_ctx.socket(zmq.SUB)
        # TODO find out if it does something and if it does, depend on max_discard
        # (for now, we just set it to 0, the default, to never discard messages)
        if hasattr(self._data, "rcvhwm"):  # zmq v3+
            self._data.rcvhwm = 0
        else:  # zmq v2
            self._data.hwm = 0
        self._data.connect("ipc://" + uri)
コード例 #5
0
 def unsubscribe(self, listener):
     with self._lock:
         count_before = len(self._listeners)
         self._listeners.discard(WeakMethod(listener))
         count_after = len(self._listeners)
         logging.debug("Listener %r unsubscribed, now %d subscribers", listener, count_after)
         if count_before > 0 and count_after == 0:
             self.stop_generate()
コード例 #6
0
 def __init__(self, *args, **kwargs):
     """
     notifier (callable): if present, will be called with the list itself
       whenever it's changed.
     """
     if "notifier" in kwargs:
         notifier = kwargs.pop("notifier")
         self._notifier = WeakMethod(notifier)
     else:
         logging.debug("Creating notifying list without notifier")
     list.__init__(self, *args, **kwargs)
コード例 #7
0
    def unsubscribe(self, listener):
        with self._lock:
            count_before = self._count_listeners()
            if isinstance(listener, basestring):
                # remove string from listeners
                self._remote_listeners.discard(listener)
            else:
                self._listeners.discard(WeakMethod(listener))

            count_after = self._count_listeners()
            logging.debug("Listener %r unsubscribed, now %d subscribers on %s", listener, count_after, self._global_name)
            if count_before > 0 and count_after == 0:
                self.stop_generate()
コード例 #8
0
    def subscribe(self, listener):
        with self._lock:
            count_before = self._count_listeners()

            # add string to listeners if listener is string
            if isinstance(listener, basestring):
                self._remote_listeners.add(listener)
            else:
                assert callable(listener)
                self._listeners.add(WeakMethod(listener))

            logging.debug("Listener %r subscribed, now %d subscribers on %s", listener, self._count_listeners(), self._global_name)
            if count_before == 0:
                self.start_generate()
コード例 #9
0
    def subscribe(self, listener, init=False):
        """
        Register a callback function to be called when the VigilantAttributeBase
        is changed

        listener (function): callback function which takes as argument val the
            new value
        init (boolean): if True calls the listener directly, to initialise it
        """
        assert callable(listener)
        if isinstance(listener, types.BuiltinMethodType):
            self._listeners.add(listener)
        else:
            self._listeners.add(WeakMethod(listener))

        if init:
            listener(self.value)
コード例 #10
0
    def subscribe(self, listener, init=False, **kwargs):
        """
        Register a callback function to be called when the VigilantAttributeBase
        is changed

        listener (function): callback function which takes as argument val the
            new value
        init (boolean): if True calls the listener directly, to initialise it

        Additional keyword arguments can be provided. They will be passed to
        listener *ONLY ONCE* and only if `init` is True!

        One of the reasons for this, is that we cannot easily store the `kwargs`
        into the `_listeners` set, because `dicts` are not hashable.
        """
        assert callable(listener)
        self._listeners.add(WeakMethod(listener))

        if init:
            listener(self.value, **kwargs)
コード例 #11
0
    def __init__(self, notifier, uri, max_discard, zmq_ctx):
        """
        notifier (callable): method to call when a new value arrives
        uri (string): unique string to identify the connection
        max_discard (int)
        zmq_ctx (0MQ context): available 0MQ context to use
        """
        threading.Thread.__init__(self, name="zmq for VA " + uri)
        self.daemon = True
        self.uri = uri
        self.max_discard = max_discard
        self._ctx = zmq_ctx
        # don't keep strong reference to notifier so that it can be garbage
        # collected normally and it will let us know then that we can stop
        self.w_notifier = WeakMethod(notifier)

        # create a zmq synchronised channel to receive commands
        self._commands = zmq_ctx.socket(zmq.PAIR)
        self._commands.connect("inproc://" + uri)

        # create a zmq subscription to receive the data
        self.data = zmq_ctx.socket(zmq.SUB)
        self.data.connect("ipc://" + uri)
コード例 #12
0
 def unsubscribe(self, listener):
     self._listeners.discard(WeakMethod(listener))