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)
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)
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)
def unsubscribe(self, listener): self._listeners.discard(WeakMethod(listener))