예제 #1
0
 def test_subscription(self):
     service = PubSub('test_subscription')
     sub = Subscriber('sub')
     service.subscribe(sub, sub.key, 'topic', sub.cb1)
     subscriptions = service.subscriptions()
     self.assertIn('topic', subscriptions)
     self.assertIn((sub, sub.key, sub.cb1), subscriptions['topic'])
예제 #2
0
 def test_publish_filter(self):
     service = PubSub('test_publish_filter')
     subscribers = [Subscriber('sub%d' % i) for i in range(1, 5)]
     for sub in subscribers:
         service.subscribe(sub, sub.key, 'topic', sub.cb1)
     service.publish('topic', 'event1')
     for sub in subscribers:
         self.assertIn((sub, Subscriber.cb1, 'topic', 'event1'),
                       log['callbacks'])
     service.publish('topic', 'event2', subscribers[0].key)
     for sub in subscribers[:1]:
         self.assertNotIn((sub, Subscriber.cb1, 'topic', 'event2'),
                          log['callbacks'])
     for sub in subscribers[1:]:
         self.assertIn((sub, Subscriber.cb1, 'topic', 'event2'),
                       log['callbacks'])
     clear_log()
     service.publish('topic', 'event3',
                     subscribers[0].key, [s.key for s in subscribers[:3]])
     for sub in [subscribers[0], subscribers[3]]:
         self.assertNotIn((sub, Subscriber.cb1, 'topic', 'event3'),
                          log['callbacks'])
     for sub in subscribers[1:3]:
         self.assertIn((sub, Subscriber.cb1, 'topic', 'event3'),
                       log['callbacks'])
예제 #3
0
 def test_persistent_subscriptions(self):
     service = PubSub('test_pseristsent_subscriptions')
     sub = Subscriber('sub')
     service.subscribe(sub, sub.key, 'topic', sub.cb1)
     del service
     service = PubSub('test_pseristsent_subscriptions')
     subscriptions = service.subscriptions()
     self.assertIn('topic', subscriptions)
     self.assertIn((sub, sub.key, sub.cb1), subscriptions['topic'])
예제 #4
0
 def test_duplicate_subscription(self):
     service = PubSub('test_duplicate_subscription')
     sub = Subscriber('sub')
     local_dict = WeakValueDictionary()
     service.subscribe(sub, sub.key, 'topic', sub.cb1)
     service.subscribe(sub, sub.key, 'topic', sub.cb1)
     subscriptions = service.subscriptions()
     self.assertIn('topic', subscriptions)
     self.assertEqual(len(subscriptions['topic']), 1)
     self.assertIn((sub, sub.key, sub.cb1), subscriptions['topic'])
예제 #5
0
 def test_weak_subscriptions(self):
     service = PubSub('test_weak_subscriptions')
     sub = Subscriber('sub')
     weaksub = weakref.ref(sub)
     service.subscribe(sub, sub.key, 'topic', sub.cb1)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 1)
     self.assertIn('topic', subscriptions)
     self.assertIn((sub, sub.key, sub.cb1), subscriptions['topic'])
     del subscriptions
     del sub
     gc.collect()
     self.assertEqual(weaksub(), None)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 0)
 def testGeoFeed(self):
     item = {
         'topic': 'T',
         'key': 'K',
         'latitude': 39,
         'longitude': -79
     }
     id = GeoFeed.publish(**item)
     self.assertEqual(id, item['key'])
     time.sleep(2)
     item['key'] = 'L' 
     id = GeoFeed.publish(**item)
     self.assertEqual(id, item['key'])
 
     last_published = '9999'
     for doc in GeoFeed.list(item['topic']):
         self.assertLess(doc['published'], last_published)
         last_published = doc['published']
     
     for doc in GeoFeed.list('NOT_FOUND'):
         self.assertFalse('Should never get here')        
     
     doc = GeoFeed.get(item['topic'], item['key'])
     self.assertIsNotNone(doc)
     
     #set up PubSub subscription so that a task is created when an item is published to the feed
     sub_url = "/pubsub/task" 
     event=GeoFeed._indexname(item['topic'])
     channel='ProcessNew%s' % item['topic']
     sub_data = {'secret': 'SECRET', 'channel': channel, 'pubname': 'key'}
     PubSub.subscribe (event, sub_url, sub_data)
     
     # now publish a new item to the feed.  This should trigger creation of a new task in the queue
     id = GeoFeed.publish(**item)
     
     # need to manually process the task queue because we're in test mode
     response = self.executeTask()  # /pubsub/notify
     self.assertEqual (response.json['status'], 'OK')
     response = self.executeTask() # /pubsub/task
     self.assertEqual (response.json['status'], 'OK')
     
     # Now make sure there is a task in the queue
     queue = TaskQueue()
     lease = queue.lease (channel=channel)
     self.assertIsNotNone(lease)
     self.assertEqual(lease['id'], response.json['id'])
     self.assertEqual(lease['content']['pub_data']['key'], item['key'])
예제 #7
0
 def test_subscription_filter(self):
     service = PubSub('test_subscription_filter')
     sub1 = Subscriber('sub1')
     sub2 = Subscriber('sub2')
     service.subscribe(sub1, sub1.key, 'topic1', sub1.cb1)
     service.subscribe(sub1, sub1.key, 'topic1', sub1.cb2)
     service.subscribe(sub1, sub1.key, 'topic2', sub1.cb1)
     service.subscribe(sub1, sub1.key, 'topic2', sub1.cb2)
     service.subscribe(sub2, sub2.key, 'topic1', sub2.cb1)
     service.subscribe(sub2, sub2.key, 'topic1', sub2.cb2)
     service.subscribe(sub2, sub2.key, 'topic2', sub2.cb1)
     service.subscribe(sub2, sub2.key, 'topic2', sub2.cb2)
     subscriptions = service.subscriptions(subscriber=sub2)
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertNotIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertNotIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
     subscriptions = service.subscriptions(key=sub1.key)
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertNotIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertNotIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertNotIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertNotIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
     subscriptions = service.subscriptions(topic='topic1')
     self.assertEqual(len(subscriptions), 1)
     self.assertIn('topic1', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertNotIn('topic2', subscriptions)
     subscriptions = service.subscriptions(callback=sub1.cb1)
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertNotIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertNotIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertNotIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertNotIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
    def testPubSub(self):
        sub_data = {'secret': 'SECRET'}
        id = PubSub.subscribe ('EVENT', 'not_an_url', sub_data)
        self.assertTrue (PubSub.unsubscribe (id))
        self.assertFalse (PubSub.unsubscribe (id))

        pub_data = {'message': 123}
        self.assertEqual(0, PubSub.publish ('EVENT', pub_data))
        PubSub.subscribe ('EVENT', 'not_an_url', sub_data)
        self.assertEqual(1, PubSub.publish ('EVENT', pub_data))
        response = self.executeTask() # /pubsub/notify
        self.assertEqual(response.status_int, 200)
        response.mustcontain ('unknown url type')
        
        url = "/pubsub/test" 
        PubSub.subscribe ('EVENT2', url, sub_data)
        self.assertEqual(1, PubSub.publish ('EVENT2', pub_data))
        response = self.executeTask()  # /pubsub/notify
        self.assertEqual (response.json['status'], 'OK')
        response = self.executeTask() # /pubsub/test
        self.assertEqual (response.json['pub_data']["message"], 123)

        url = "/pubsub/task" 
        sub_data = {'secret': 'SECRET', 'channel': 'CHANNEL', 'taskname': 'NAME'}
        PubSub.subscribe ('EVENT3', url, sub_data)
        self.assertEqual(1, PubSub.publish ('EVENT3', pub_data))
        response = self.executeTask()  # /pubsub/notify
        self.assertEqual (response.json['status'], 'OK')
        response = self.executeTask() # /pubsub/task
        self.assertEqual (response.json['status'], 'OK')
        queue = TaskQueue()
        lease = queue.lease (channel='CHANNEL')
        self.assertIsNotNone(lease)
        self.assertEqual(lease['id'], response.json['id'])
예제 #9
0
 def test_mutliple_subscriptions(self):
     service = PubSub('test_multiple_subscription')
     sub1 = Subscriber('sub1')
     sub2 = Subscriber('sub2')
     service.subscribe(sub1, sub1.key, 'topic1', sub1.cb1)
     service.subscribe(sub1, sub1.key, 'topic1', sub1.cb2)
     service.subscribe(sub1, sub1.key, 'topic2', sub1.cb1)
     service.subscribe(sub1, sub1.key, 'topic2', sub1.cb2)
     service.subscribe(sub2, sub2.key, 'topic1', sub2.cb1)
     service.subscribe(sub2, sub2.key, 'topic1', sub2.cb2)
     service.subscribe(sub2, sub2.key, 'topic2', sub2.cb1)
     service.subscribe(sub2, sub2.key, 'topic2', sub2.cb2)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
예제 #10
0
    def test_publish(self):

        def callback(topic, event):
            log['callbacks'].append((callback, topic, event))
            pass

        service = PubSub('test_publish')
        sub = Subscriber('sub')
        service.subscribe(sub, sub.key, 'topic', sub.cb1)
        service.subscribe(sub, sub.key, 'topic', sub.cb2)
        service.subscribe(sub, sub.key, 'topic2', sub.cb2)
        service.subscribe(sub, sub.key, 'topic2', callback)
        service.publish('topic', 'event')
        service.publish('topic2', 'event2')
        self.assertEqual(len(log['callbacks']), 4)
        self.assertIn((sub, Subscriber.cb1, 'topic', 'event'),
                      log['callbacks'])
        self.assertIn((sub, Subscriber.cb2, 'topic', 'event'),
                      log['callbacks'])
        self.assertIn((sub, Subscriber.cb2, 'topic2', 'event2'),
                      log['callbacks'])
        self.assertIn((callback, 'topic2', 'event2'), log['callbacks'])
예제 #11
0
def handler(signum, frame):
    logger.info('got term... raising TermException')
    raise TermException()


signal.signal(signal.SIGTERM, handler)


def create_data():
    logger.info("callback invoked")
    return {"data": "here is some data from server"}


def make_query_callback(data):
    logger.info('got request of: %s' % data)
    ps.publish('return_result', create_data())
    return


ps = PubSub('AWS', topic_arn=os.environ['AWS_SNS_ARN'], logger=logger)
make_query_subscription = ps.subscribe('make_query',
                                       callback=make_query_callback)

try:
    while True:
        time.sleep(100)
except:
    logger.info('terminating... dropping subscriber')
    make_query_subscription.unsubscribe()
예제 #12
0
#######################################################################################
class Counter:
    def __init__(self):
        self.value = 0

    def on_button(self, pin):
        self.value += 1
        pubsub.publish('counter', self.value)

    def on_timer(self):
        self.value += 100
        pubsub.publish('counter', self.value)


counter = Counter()

pubsub.subscribe('button', counter.on_button)
pubsub.subscribe('timer', counter.on_timer)

#######################################################################################
from util.octopus import disp7_init

d7 = disp7_init()  # 8 x 7segment display init


def display_num(value):
    d7.show(value)


pubsub.subscribe('counter', display_num)
예제 #13
0
class PubSubFactory(protocol.ServerFactory):
    protocol = PubSubProtocol

    def __init__(self, messageTimeout,
                 subscriptionTimeout, messageFormat):
        self.pubsub = PubSub(messageTimeout)
        self.subscriptionTimeout = subscriptionTimeout
        self.messageFormat = messageFormat

    def subscribe(self, request):
        urlComponents = urlparse.urlparse(request.uri)
        query = urlparse.parse_qs(urlComponents.query)

        if "channel" not in query:
            self._reportError(request,
                              "expected 'channel' in the request")
            return

        channel = tryParseInt(query["channel"][0], 0)
        if channel == 0:
            return self._reportError(request,
                              "'channel' value should be number")

        query.setdefault("time_from", [0])
        timeFrom = tryParseInt(query["time_from"][0], 0)

        query.setdefault("min_id", [0])
        mid = tryParseInt(query["min_id"][0], 0)

        notify = lambda message: self._notify(request,message)
        print "parameters", timeFrom, mid

        self.pubsub.subscribe(channel, notify,
                              request.finish,
                              timeFrom,
                              minId = mid,
                              timeoutSec = self.subscriptionTimeout)

    # --- Utilities ---
    def _notify(self, request, message):
        try:
            request.setResponseCode(200, "OK")
            message = self._normalize(message)
            print "MESSAGE: ", message
            request.write(message)
            request.finish()
        except Exception as e:
            print "Unhandled Error"
            print e

    def _normalize(self, messages):
        if len(messages) == 0:
            return self.messageFormat % ("[]", 0)

        maxId = messages[-1][0]
        messages = (m for id, m in messages)
        messages = "[%s]" % ",".join(messages)

        return self.messageFormat % (messages, maxId)

    def _reportError(self, request, errorMessage):
        request.setResponseCode(400, "error")
        request.responseHeaders.addRawHeader("Content-Type",
                                             "text/html")
        request.write("<H1>Error</H1>")
        request.write("<p>%s</p>" % errorMessage)
        request.finish()
예제 #14
0
 def test_unsubscribe(self):
     service = PubSub('test_unsubscribe')
     sub1 = Subscriber('sub1')
     sub2 = Subscriber('sub2')
     service.subscribe(sub1, sub1.key, 'topic1', sub1.cb1)
     service.subscribe(sub1, sub1.key, 'topic1', sub1.cb2)
     service.subscribe(sub1, sub1.key, 'topic2', sub1.cb1)
     service.subscribe(sub1, sub1.key, 'topic2', sub1.cb2)
     service.subscribe(sub2, sub2.key, 'topic1', sub2.cb1)
     service.subscribe(sub2, sub2.key, 'topic1', sub2.cb2)
     service.subscribe(sub2, sub2.key, 'topic2', sub2.cb1)
     service.subscribe(sub2, sub2.key, 'topic2', sub2.cb2)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     service.unsubscribe(sub2, sub2.key, 'topic2', sub2.cb2)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertNotIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
     service.unsubscribe(sub1, sub1.key, callback=sub1.cb2)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertNotIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
     service.unsubscribe(callback=sub1.cb1)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 2)
     self.assertIn('topic1', subscriptions)
     self.assertNotIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertIn('topic2', subscriptions)
     self.assertNotIn((sub1, sub1.key, sub1.cb1), subscriptions['topic2'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic2'])
     self.assertIn((sub2, sub2.key, sub2.cb1), subscriptions['topic2'])
     self.assertNotIn((sub2, sub2.key, sub2.cb2), subscriptions['topic2'])
     service.unsubscribe(callback=sub2.cb1)
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 1)
     self.assertIn('topic1', subscriptions)
     self.assertNotIn((sub1, sub1.key, sub1.cb1), subscriptions['topic1'])
     self.assertNotIn((sub1, sub1.key, sub1.cb2), subscriptions['topic1'])
     self.assertNotIn((sub2, sub2.key, sub2.cb1), subscriptions['topic1'])
     self.assertIn((sub2, sub2.key, sub2.cb2), subscriptions['topic1'])
     self.assertNotIn('topic2', subscriptions)
     service.unsubscribe()
     subscriptions = service.subscriptions()
     self.assertEqual(len(subscriptions), 0)