def createNotificationTopics(self, topicMgr=None): '''Create the notification topics. The root of the topics created is self.topicRoot. Note that if topicMgr not given, then it will be obtained by importing pubsub. Since it is important that your code control when the first import occurs, this method raises a RuntimeError if pubsub hasn't already been imported. ''' if topicMgr is None: if not pubsubconf.isPackageImported(): raise RuntimeError('your code must import pubsub first') from pubsub import pub topicMgr = pub.getDefaultTopicMgr() # see if the special topics have already been defined try: topicMgr.getTopic(self.topicRoot) except RuntimeError: # no, so create them topicMgr.newTopic( _name = self.topicRoot, _desc = 'root of all pubsub-specific topics') self._pubTopic = topicMgr.getTopic(self.topicRoot) assert hasattr(self, '_pubTopic') _createTopics(self.topics, topicMgr)
def useNotifyByPubsubMessage(pubModule=None, topicMgr=None, all=True, **kwargs): '''Will cause all of pubsub's notifications of pubsub "actions" (such as new topic created, message sent, listener subscribed, etc) to be sent out as messages. Topic will be 'pubsub' subtopics, such as 'pubsub.newTopic', 'pubsub.delTopic', 'pubsub.sendMessage', etc. The 'all' and kwargs args are the same as pubsub's setNotificationFlags(), except that 'all' defaults to True. The pubModule and topicMgr are rarely needed: * The pubModule only needs to be specfied if pubsub is not installed on the system search path (ie from pubsub import ... would fail or import wrong pubsub -- such as if pubsub is within wxPython's wx.lib package). Then pbuModule is the pub module to use:: from wx.lib.pubsub import pub from wx.lib.pubsub.utils import notification notification.useNotifyByPubsubMessage(pub) * The topicMgr only needs to be specified if you are not using the default topic manager created by pubsub.pub (or by provided pubModule). ''' if pubModule is None: from pubsub import pub as pubModule if topicMgr is None: topicMgr = pubModule.getDefaultTopicMgr() notifHandler = NotifyByPubsubMessage( topicMgr ) pubModule.addNotificationHandler(notifHandler) pubModule.setNotificationFlags(all=all, **kwargs)
def useNotifyByPubsubMessage(pubModule=None, topicMgr=None, all=True, **kwargs): '''Will cause all of pubsub's notifications of pubsub "actions" (such as new topic created, message sent, listener subscribed, etc) to be sent out as messages. Topic will be 'pubsub' subtopics, such as 'pubsub.newTopic', 'pubsub.delTopic', 'pubsub.sendMessage', etc. The 'all' and kwargs args are the same as pubsub's setNotificationFlags(), except that 'all' defaults to True. The pubModule and topicMgr are rarely needed: * The pubModule only needs to be specfied if pubsub is not installed on the system search path (ie from pubsub import ... would fail or import wrong pubsub -- such as if pubsub is within wxPython's wx.lib package). Then pbuModule is the pub module to use:: from wx.lib.pubsub import pub from wx.lib.pubsub.utils import notification notification.useNotifyByPubsubMessage(pub) * The topicMgr only needs to be specified if you are not using the default topic manager created by pubsub.pub (or by provided pubModule). ''' if pubModule is None: from pubsub import pub as pubModule if topicMgr is None: topicMgr = pubModule.getDefaultTopicMgr() notifHandler = NotifyByPubsubMessage(topicMgr) pubModule.addNotificationHandler(notifHandler) pubModule.setNotificationFlags(all=all, **kwargs)
def loop_subscribe(topic_names, listeners): topicMgr = pub.getDefaultTopicMgr() topicMgr.clearTree() num_samples = 1000 start = perf_counter() for count in range(num_samples): for listener in listeners: for topic_name in topic_names: pub.subscribe(listener, topic_name) tot_time = (perf_counter() - start) return round(tot_time, 2)
def loop_send(subscriptions: Tuple[Listener, str], messages): topicMgr = pub.getDefaultTopicMgr() topicMgr.clearTree() for listener, topic_name in subscriptions: pub.subscribe(listener, topic_name) num_samples = 1000 start = perf_counter() for count in range(num_samples): for topic_name, kwargs in messages: pub.sendMessage(topic_name, **kwargs) tot_time = (perf_counter() - start) return round(tot_time, 2)
def _subscribe(self): def sgetter(funcname): def realsgetter(owner, msg): return owner._subs[funcname](owner, msg) return realsgetter # wx classes throw exception if getmember is applied to the instance (self) methods = inspect.getmembers(self.__class__, inspect.ismethod) topicmgr = pub.getDefaultTopicMgr() for mname, method in methods: pubsubtopic = getattr(method, '_pubrecv', None) if pubsubtopic: self._subs[mname] = method subsgetter = sgetter(mname) if not topicmgr.getTopic(pubsubtopic, True) or not pub.isSubscribed(subsgetter, pubsubtopic): setattr(self, mname, subsgetter) pub.subscribe(subsgetter.__get__(self, self.__class__), pubsubtopic)
def testListenerChangesListenerList(): """pubsub supports un/subscribing of listeners while sendMessage in progress. This requires that the TopicManager instance properly loop over listeners, via a copy of list instead of iterator on list (since lists can't be modified while iteration in progress. This test verifies that listener receiving message can subscribe another listener to same topic, and can unsubscribe self while handling message. """ class Listeners: callCountForNewListener = 0 callCountForChanger = 0 def newListener(self): self.callCountForNewListener += 1 pub.unsubscribe(self.newListener, 'test.change-listeners') def changer(self): # first time, subscribe new listener; if don't have this, will fail in # py3 because order of listeners opposite, so unsub will happen before # the sub (which succeeds even if no listeners) and newListener will # remain subscribed. if self.callCountForChanger == 0: pub.subscribe(self.newListener, 'test.change-listeners') self.callCountForChanger += 1 testListeners = Listeners() pub.subscribe(testListeners.changer, 'test.change-listeners') topic = pub.getDefaultTopicMgr().getTopic('test.change-listeners') pub.sendMessage('test.change-listeners') assert testListeners.callCountForChanger == 1 assert testListeners.callCountForNewListener == 0 assert topic.getNumListeners() == 2 pub.sendMessage('test.change-listeners') assert testListeners.callCountForChanger == 2 assert testListeners.callCountForNewListener == 1 assert topic.getNumListeners() == 1 pub.sendMessage('test.change-listeners') assert testListeners.callCountForChanger == 3 assert testListeners.callCountForNewListener == 1
def testHandleExcept1a(): from pubsub.utils.exchandling import ExcPublisher excPublisher = ExcPublisher( pub.getDefaultTopicMgr() ) pub.setListenerExcHandler(excPublisher) # create a listener that raises an exception: from raisinglistener import getRaisingListener raisingListener = getRaisingListener() pub.setNotificationFlags(all=False) pub.subscribe(raisingListener, 'testHandleExcept1a') # first test when a listener raises an exception and exception listener also raises! class BadUncaughtExcListener: def __call__(self, listenerStr=None, excTraceback=None): raise RuntimeError('bad exception listener!') handler = BadUncaughtExcListener() pub.subscribe(handler, ExcPublisher.topicUncaughtExc) pytest.raises(pub.ExcHandlerError, pub.sendMessage, 'testHandleExcept1a') pub.unsubscribe(handler, ExcPublisher.topicUncaughtExc)
def testHandleExcept1a(): from pubsub.utils.exchandling import ExcPublisher excPublisher = ExcPublisher(pub.getDefaultTopicMgr()) pub.setListenerExcHandler(excPublisher) # create a listener that raises an exception: from raisinglistener import getRaisingListener raisingListener = getRaisingListener() pub.setNotificationFlags(all=False) pub.subscribe(raisingListener, 'testHandleExcept1a') # first test when a listener raises an exception and exception listener also raises! class BadUncaughtExcListener: def __call__(self, listenerStr=None, excTraceback=None): raise RuntimeError('bad exception listener!') handler = BadUncaughtExcListener() pub.subscribe(handler, ExcPublisher.topicUncaughtExc) pytest.raises(pub.ExcHandlerError, pub.sendMessage, 'testHandleExcept1a') pub.unsubscribe(handler, ExcPublisher.topicUncaughtExc)
def _subscribe(self): def sgetter(funcname): def realsgetter(owner, msg): return owner._subs[funcname](owner, msg) return realsgetter # wx classes throw exception if getmember is applied to the instance (self) methods = inspect.getmembers(self.__class__, inspect.ismethod) topicmgr = pub.getDefaultTopicMgr() for mname, method in methods: pubsubtopic = getattr(method, '_pubrecv', None) if pubsubtopic: self._subs[mname] = method subsgetter = sgetter(mname) if not topicmgr.getTopic(pubsubtopic, True) or not pub.isSubscribed( subsgetter, pubsubtopic): setattr(self, mname, subsgetter) pub.subscribe(subsgetter.__get__(self, self.__class__), pubsubtopic)
def createNotificationTopics(self, topicMgr=None): '''Create the notification topics. The root of the topics created is self.topicRoot. Note that if topicMgr not given, then it will be obtained by importing pubsub. Since it is important that your code control when the first import occurs, this method raises a RuntimeError if pubsub hasn't already been imported. ''' if topicMgr is None: if not globalsettings.isPackageImported(): raise RuntimeError('your code must import pubsub first') from pubsub import pub topicMgr = pub.getDefaultTopicMgr() # see if the special topics have already been defined try: topicMgr.getTopic(self.topicRoot) except RuntimeError: # no, so create them self._pubTopic = topicMgr.getOrCreateTopic(self.topicRoot) self._pubTopic.setDescription('root of all pubsub-specific topics') _createTopics(self.topics, topicMgr)
import pytest from pubsub import pub try: Path.write_text # new in Python 3.5 except AttributeError: def write_text(path: Path, text: str): with path.open('w') as f: f.write(text) Path.write_text = write_text topicMgr = pub.getDefaultTopicMgr() def try_call(max_times: int, func: callable, *args: Any, func_on_fail: callable = None) -> int: """ Try to call a function. :param func: the function to call :param args: arguments to give to function :param max_times: maximum number of attempts :param func_on_fail: when call fails, call this function :return: # of calls left (so if 0, ran out of calls, i.e. tried more than max_times) """ retries = 0
from typing import Dict, Any import logging from pubsub import pub from liberalguardians.common.logging import StyleAdapter logger = StyleAdapter(logging.getLogger(__name__)) logger.info('topics initiatlization') PLAYER_LOG_NAME = 'log' DESCRIPTION_NAME = 'description.value' DEFAULT_DESCRIPTION_NAME = 'description.default' TEXT_DESCRIPTION_NAME = 'description.text' topic_manager = pub.getDefaultTopicMgr() logger.debug('topics creation started') def _prot_args(args: Dict[str, Any] = None) -> None: pass def _prot_value(value: Any) -> None: pass log = topic_manager.getOrCreateTopic(PLAYER_LOG_NAME, _prot_args) description = topic_manager.getOrCreateTopic(DESCRIPTION_NAME, _prot_args)
def setUpClass(cls): cls.topicMgr = pub.getDefaultTopicMgr() cls.topicMgr.delTopic('echo')
def __init__(self, import_name): """Creates the Chalice GitHubApp Blueprint.""" super().__init__(import_name) pub.setListenerExcHandler(ExcPublisher(pub.getDefaultTopicMgr()))
python -m timeit -n1 "import perf; perf.runTest()" :copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. :license: BSD, see LICENSE.txt for details. """ from pathlib import Path from time import perf_counter from typing import Tuple from pubsub import pub from pubsub.core import Listener topicMgr = pub.getDefaultTopicMgr() def loop_subscribe(topic_names, listeners): topicMgr = pub.getDefaultTopicMgr() topicMgr.clearTree() num_samples = 1000 start = perf_counter() for count in range(num_samples): for listener in listeners: for topic_name in topic_names: pub.subscribe(listener, topic_name) tot_time = (perf_counter() - start)
def OnClose(self, event): pub.getDefaultTopicMgr().delTopic('logviewer') # self.Destroy()
def testNotifications(): class Handler(INotificationHandler): def __init__(self): self.resetCounts() def resetCounts(self): self.counts = dict(send=0, sub=0, unsub=0, delt=0, newt=0, dead=0, all=0) def notifySubscribe(self, pubListener, topicObj, newSub): self.counts['sub'] += 1 def notifyUnsubscribe(self, pubListener, topicObj): self.counts['unsub'] += 1 def notifyDeadListener(self, pubListener, topicObj): self.counts['dead'] += 1 def notifySend(self, stage, topicObj, pubListener=None): if stage == 'pre': self.counts['send'] += 1 def notifyNewTopic(self, topicObj, description, required, argsDocs): self.counts['newt'] += 1 def notifyDelTopic(self, topicName): self.counts['delt'] += 1 notifiee = Handler() pub.addNotificationHandler(notifiee) pub.setNotificationFlags(all=True) def verify(**ref): gc.collect() # for pypy: the gc doesn't work the same as cpython's for key, val in notifiee.counts.items(): if key in ref: assert val == ref[key], "\n%s\n%s" % (notifiee.counts, ref) else: assert val == 0, "%s = %s, expected 0" % (key, val) notifiee.resetCounts() verify() def testListener(): pass def testListener2(): pass def testListener3(): pass class TestListener: def __call__(self): pass def __del__(self): pass testListener = TestListener() topicMgr = pub.getDefaultTopicMgr() topicMgr.getOrCreateTopic('newTopic') verify(newt=1) pub.subscribe(testListener, 'newTopic') pub.subscribe(testListener2, 'newTopic') pub.subscribe(testListener3, 'newTopic') verify(sub=3) pub.sendMessage('newTopic') verify(send=1) verify(dead=0) del testListener del testListener3 verify(dead=2) pub.unsubscribe(testListener2, 'newTopic') verify(unsub=1) topicMgr.delTopic('newTopic') verify(delt=1)
def testNotifications(): class Handler(INotificationHandler): def __init__(self): self.resetCounts() def resetCounts(self): self.counts = dict(send=0, sub=0, unsub=0, delt=0, newt=0, dead=0, all=0) def notifySubscribe(self, pubListener, topicObj, newSub): self.counts['sub'] += 1 def notifyUnsubscribe(self, pubListener, topicObj): self.counts['unsub'] += 1 def notifyDeadListener(self, pubListener, topicObj): self.counts['dead'] += 1 def notifySend(self, stage, topicObj, pubListener=None): if stage == 'pre': self.counts['send'] += 1 def notifyNewTopic(self, topicObj, description, required, argsDocs): self.counts['newt'] += 1 def notifyDelTopic(self, topicName): self.counts['delt'] += 1 notifiee = Handler() pub.addNotificationHandler(notifiee) pub.setNotificationFlags(all=True) def verify(**ref): gc.collect() # for pypy: the gc doesn't work the same as cpython's for key, val in notifiee.counts.items(): if key in ref: assert val == ref[key], "\n%s\n%s" % (notifiee.counts, ref) else: assert val == 0, "%s = %s, expected 0" % (key, val) notifiee.resetCounts() verify() def testListener(): pass def testListener2(): pass def testListener3(): pass class TestListener: def __call__(self): pass def __del__(self): pass testListener = TestListener() topicMgr = pub.getDefaultTopicMgr() topicMgr.getOrCreateTopic('newTopic') verify(newt=1) pub.subscribe(testListener, 'newTopic') pub.subscribe(testListener2, 'newTopic') pub.subscribe(testListener3, 'newTopic') verify(sub=3) pub.sendMessage('newTopic') verify(send=1) verify(dead=0) del testListener del testListener3 verify(dead=2) pub.unsubscribe(testListener2,'newTopic') verify(unsub=1) topicMgr.delTopic('newTopic') verify(delt=1)