示例#1
0
 def doSubscribeRequest(self, fromrouter, interval, evtype, source):
     """
     Helper function to register an event forwarding subscription for 
     the designated event type and source with the routers from which
     such events may be received.
     
     TODO: logic to keep maximum subscription interval
     """
     ### Trace("%s doSubscribeRequest %us, (%s,%s) from %s"%(self.getUri(),interval,evtype,source,fromrouter), "EventLib.EventRouter")
     if interval != 0:
         # subscribing
         fwds = self._fwdtable.find(evtype, source)
         if fromrouter not in self._fwdtable.find(evtype, source):
             # new subscription
             self._fwdtable.insert(evtype, source, fromrouter)
             Trace("%s _fwdtable inserted: (%s,%s) -> %s"%(self.getUri(),evtype,source,str(fromrouter)), context="EventLib.EventRouter")
             self._fwdcount += 1
     else:
         # unsubscribing
         removed = self._fwdtable.remove(evtype, source, fromrouter)
         Trace("%s _fwdtable removed: %s"%(self.getUri(),map(str,removed)), context="EventLib.EventRouter")
         if removed:
             self._fwdcount -= len(removed)
             Trace("self._fwdcount: %u"%(self._subcount), context="EventLib.EventRouter")
     return
示例#2
0
 def deliver(self, event):
     """
     Local delivery of an event.
     
     Returns a Deferred object with the final status of the deliver operation.
     """
     Trace("%s deliver (%s,%s,%s)"%
           (self.getUri(), event.getType(), event.getSource(), event.getPayload()), 
           context="EventLib.EventPubSub")
     (evtyp, evsrc) = getEventTypeSource(event)
     if isSubscribeEvent(evtyp):
         for (e,t,handler) in self._sub.iterateWild(evtyp, evsrc):
             # Deliver to watchers only (no wildcard event type)
             if e == URI.EventSubscribeType:
                 Trace("%s - to watcher %s"%(self.getUri(), handler.getUri()), 
                     context="EventLib.EventPubSub")
                 sts = handler.handleEvent(event)
                 if sts.syncValue() != StatusVal.OK: return sts
     else:
         for handler in self._sub.iterate(evtyp, evsrc):
             Trace("%s - to handler %s (%s,%s)"%(self.getUri(), handler.getUri(), event.getType(), event.getSource()), 
                 context="EventLib.EventPubSub")
             sts = handler.handleEvent(event)
             if sts.syncValue() != StatusVal.OK: return sts
     return makeDeferred(StatusVal.OK)
示例#3
0
 def receive(self, fromrouter, envelope):
     """
     Receive an event from an external event router.
     
     The event received is wrapped in a forwarding envelope, which contains
     additional information about the event delivery path that is used, possibly
     among other things, to detect event forwarding loops.
     
     Returns a Deferred object with the final status of the receive operation.
     """
     sts   = makeDeferred(StatusVal.OK)
     event = envelope.unWrap(self.getUri())      # unWrap handles loop-detection
     if event:
         Trace("%s receive %s from %s"%(self.getUri(),str(event), fromrouter), "EventLib.EventRouter")
         self.deliver(event)
         sub = openSubscribeEvent(isSubscribeEvent, event)
         Trace("%s openSubscribeEvent %s"%(self.getUri(),sub), "EventLib.EventRouter")
         if sub:
             # New subscription request
             self.doSubscribeRequest(fromrouter, sub[2], sub[3], sub[4])
         newenv = envelope.nextHop(self.getUri())
         sts = self.forward(event, newenv)
         if sub and sub[2] != 0 and sts.syncValue() != StatusVal.OK:
             # Undo subscription
             self.doSubscribeRequest(fromrouter, 0, sub[3], sub[4])
     return sts
示例#4
0
    def watch(self, interval, handler, evtype=None):
        """
        Request to receive notice of subscribe/unsubscribe events for a given
        event type.
        
        (Currently there is no option to also select on subscriber.)

        Returns a Deferred status value is returned indicating the outcome of the subscribe 
        operation - StatusVal.SUBSCRIBED indicates a successful outcome.
        
        HACK:  for subscription notification events, the subscribed event type is treated as 
        the source for subscription.  This avoids having to keep a separate table for watchers.
        """
        Trace("%s watch %us, handler %s to %s"%(self.getUri(), interval, str(handler), evtype), 
              context="EventLib.EventPubSub")
        sts = self.subscribe(interval, handler, evtype=URI.EventSubscribeType, source=evtype)
        if sts.syncValue() == StatusVal.SUBSCRIBED:
            # Scan existing subscriptions for immediate watch events
            Trace("- scanning subscriptions", context="EventLib.EventPubSub")
            event = makeEvent(evtype=URI.EventSubscribeType, source=evtype)
            for (t,s,h) in self._sub.iterateWild(evtype, None):
                Trace("- subscribed (%s,%s,%s)"%(t,s,h), context="EventLib.EventPubSub")
                handler.handleEvent(event)
            pass
        return sts
 def testBlockingEventDelivery(self):
     es = makeEventAgent(uri="es")
     eh = makeEventHandler(uri="eh",
                           handler=eventHandlerBlocking,
                           initSubscription=subHandler,
                           endSubscription=unsubHandler)
     eh.subcount = 0
     eh.evcount = 0
     evtyp = "R3Events1/ev1"  # Select event routed R3 -> R1 -> R2 ..
     evsrc = "R3Source1/src1"  # .. (see setUp)
     ev = makeEvent(evtype=evtyp, source=evsrc)
     sts = self.R2.subscribe(60, eh, evtype=evtyp, source=evsrc)
     Trace("Subscribe returned", "EventLib.TestEventRouterThreaded")
     time.sleep(0.1)  # Allow subscribe time to propagate
     Trace("Subscribed", "EventLib.TestEventRouterThreaded")
     self.assertEqual(eh.evcount, 0)
     sts = self.R3.publish(es, ev)
     self.assertEqual(eh.evcount, 0)  # Not delivered immediately ...
     Trace("Before sleep", "EventLib.TestEventRouterThreaded")
     time.sleep(1.5)  # Note: evcent handler blocks for 1 sec
     Trace("After sleep: eh.evcount %d" % (eh.evcount),
           "EventLib.TestEventRouterThreaded")
     self.assertEqual(eh.evcount, 1)  # ... but  sometime after a second
     self.assertEqual(eh.event.getType(), evtyp)
     self.assertEqual(eh.event.getSource(), evsrc)
     Trace("testBlockingEventDelivery OK",
           "EventLib.TestEventRouterThreaded")
     return
示例#6
0
 def subscribe(self, interval, handler, evtype=None, source=None):
     """
     Subscribe an event handler to an event/source combination.
     
     'interval' is a time interval, in seconds, for which the subscription 
     is to be maintained - if zero, no subscription is created, and any 
     existing subscription is cancelled.
     
     Returns a Deferred status value is returned indicating the outcome 
     of the operation.
     """
     Trace("%s subscribe %us, handler %s to (%s,%s)"%
               (self.getUri(), interval, str(handler), evtype, source), 
           context="EventLib.EventPubSub")
     sts = self.unsubscribe(handler, evtype, source)
     if interval != 0:
         self._sub.insert(evtype, source, handler)
         self._subcount += 1
         handler.initSubscription(StatusVal.SUBSCRIBED)
         # Publish subscribe request and notify events
         sts = self.publishSubscription(handler, interval, evtype, source)
         if sts.syncValue() != StatusVal.OK:
             Trace("publish subscription returns %s"%(str(sts.syncValue())), context="EventLib.EventPubSub")
             self.unsubscribe(handler, evtype, source)
         else:
             sts = makeDeferred(StatusVal.SUBSCRIBED)
     return sts
def eventHandlerBlocking(h, e):
    Trace("%s eventHandlerBlocking %s" % (h, str(e)),
          "EventLib.TestEventRouterThreaded")
    time.sleep(1.0)
    h.evcount += 1
    h.event = e
    Trace("%s eventHandlerBlocking - return" % (h),
          "EventLib.TestEventRouterThreaded")
    return makeDeferred(StatusVal.OK)
 def getQueuedItem(self):
     """
     Wait for an item to be queued, then return it.
     """
     Trace("%s getQueuedItem ..." % (self.getUri()),
           context="EventLib.EventRelayHTTPC")
     item = self._queue.get()
     Trace("%s getQueuedItem (%s)" % (self.getUri(), item),
           context="EventLib.EventRelayHTTPC")
     self._event.set()
     return item
示例#9
0
 def tearDown(self):
     Trace("tearDown","TestEventPubSub")
     if self.a: self.router.unsubscribe(self.a, evtype="t1", source="s1")
     if self.b: self.router.unsubscribe(self.b, evtype="t2", source="s1")
     if self.c: self.router.unsubscribe(self.c, evtype="t1", source="s2")
     if self.d: self.router.unsubscribe(self.d, evtype="t2", source="s2")
     if self.e: self.router.unsubscribe(self.e, evtype="t1")
     if self.f: self.router.unsubscribe(self.f, source="s1")
     if self.g: self.router.unsubscribe(self.g)
     if self.h: self.router.unsubscribe(self.h, evtype="t2", source="s1")
     Trace("tearDown exit","TestEventPubSub")
     return
示例#10
0
 def close(self):
     """
     Shut down the event router thread
     """
     Trace("%s close" % (self.getUri()), "EventLib.EventRelayHTTPC")
     self._httpcon.close()
     self._closing = True
     self._event.set()
     self._queue.put(["closedown", []])
     self._thread.join()
     Trace("%s closed" % (self.getUri()), "EventLib.EventRelayHTTPC")
     return
示例#11
0
 def close(self):
     """
     Shut down the event router thread
     """
     # assert False,"EventRelayHTTPS .close called"
     Trace("%s close" % (self.getUri()), "EventLib.EventRelayHTTPS")
     self._closing = True
     self._event.set()
     self._queue.put(["closedown", []])
     self._server.stop()
     Trace("%s stopped" % (self.getUri()), "EventLib.EventRelayHTTPS")
     self._thread.join()
     Trace("%s closed" % (self.getUri()), "EventLib.EventRelayHTTPS")
     return
示例#12
0
 def getQueuedItem(self):
     """
     Wait for an item to be queued, then return it.
     """
     try:
         item = self._queue.get(timeout=QUEUE_WAIT_TIMEOUT)
     except Empty:
         Trace("%s getQueuedItem: timeout" % (self.getUri()),
               "EventLib.EventRelayHTTPS")
         item = ["idle", []]
     Trace("%s getQueuedItem: item %s" % (self.getUri(), str(item)),
           "EventLib.EventRelayHTTPS")
     self._event.set()
     return item
示例#13
0
 def testWatch8(self):
     Trace("testWatch8","TestEventPubSub")
     self.setUpRouter()
     h1 = MyEventHandler("H1")
     w1 = MyEventHandler("W1")
     self.router.watch(5, w1, evtype="t1")
     self.router.subscribe(60, h1, evtype="t1", source="s1")
     assert w1.isWatched(),"Watch for t1 not triggered on subscribe"
     ev = w1.getSubEvent()
     Trace("testWatch8 - ev %s:%s"%(str(ev),repr(ev.getPayload())),"TestEventPubSub")
     assert ev.getType() == URI.EventSubscribeType, "Subscribe event type must be URI.EventSubscribeType"
     assert ev.getSource() == h1.getUri(), "Subscribe event agent not handler URI"
     assert ev.getPayload()[0] == 60,   "Subscribe payload[0] not interval"
     assert ev.getPayload()[1] == "t1", "Subscribe payload[1] not subscribed event type"
     assert ev.getPayload()[2] == "s1", "Subscribe payload[2] not subscribed event source"
     return
示例#14
0
 def testEventTypeSourceDict2(self):
     Trace("testEventTypeSourceDict2","TestEventPubSub")
     # Construct a test dinctionary
     ed = EventTypeSourceDict()
     tsvs = [ ("bt","bs","B1"), ("bt","bs","B2")
            , ("at","as","A1"), ("at","as","A2")
            , (None,None,"N1"), (None,None,"N2")
            ]
     for (t,s,v) in tsvs: ed.insert(t, s, v)
     self.assertEqual(list(ed.iterateAll()), tsvs)
     self.assertEqual(ed.count(), 6)
     # Test wildcard scanning operations
     self.assertEqual(list(ed.iterateWild(None,None)), tsvs)
     self.assertEqual(list(ed.iterateWild("at","as")),
                      [("at","as","A1"), ("at","as","A2"), (None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild("at",None)),
                      [("at","as","A1"), ("at","as","A2"), (None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild(None,"as")),
                      [("at","as","A1"), ("at","as","A2"), (None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild("bt","bs")),
                      [("bt","bs","B1"), ("bt","bs","B2"), (None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild("bt",None)),
                      [("bt","bs","B1"), ("bt","bs","B2"), (None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild(None,"bs")),
                      [("bt","bs","B1"), ("bt","bs","B2"), (None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild("ct","cs")),
                      [(None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild("ct",None)),
                      [(None,None,"N1"), (None,None,"N2")])
     self.assertEqual(list(ed.iterateWild(None,"cs")),
                      [(None,None,"N1"), (None,None,"N2")])
     return
def eventHandlerQueueing(h, e):
    Trace("%s eventHandlerQueueing %s" % (h, str(e)),
          "EventLib.TestEventRouterThreaded")
    h.evcount += 1
    h.event = e
    h.queue.append(e)
    return makeDeferred(StatusVal.OK)
示例#16
0
 def testWatchPrior1(self):
     Trace("testWatchPrior1","TestEventPubSub")
     self.setUpRouter()
     h1 = MyEventHandler("H1")
     w1 = MyEventHandler("W1")
     self.router.subscribe(60, h1, evtype="t1", source="s1")
     self.router.watch(5,w1,evtype="t1")
     assert w1.isWatched(),"Watch t1 not triggered for subscribe that precedes watch"
示例#17
0
 def forward(self, event, env):
     """
     Internal function to process event received from HTTP connection: 
     add new hop to envelope and pass it straight on to the associated router object.
     """
     Trace("%s forward %s" % (self.getUri(), event),
           "EventLib.EventRelayHTTPC")
     return self._router.receive(self, env.nextHop(self.getUri()))
示例#18
0
 def testUnsubscribe2(self):
     Trace("testUnsubscribe2","TestEventPubSub")
     self.setUpRouter()
     self.router.unsubscribe(self.handlers[4], evtype="t1")
     self.router.unsubscribe(self.handlers[5], source="s1")
     #                  A      B      C      D      E      F      G      H
     expectTriggered = (True,  False, False, False, False, False, True,  False)
     self.doTestPublish("t1","s1",expectTriggered)
示例#19
0
 def stop(self):
     """
     Request server to stop.
     """
     Trace("%s stop" % (self._relay.getUri()), "EventLib.EventRelayHTTPS")
     self._run = False
     time.sleep(self._timeout + 1)
     self.socket.close()
示例#20
0
 def tearDown(self):
     Trace("TearDown", "TestEventRouterHTTP")
     if self.R1: self.R1.close()
     if self.R2: self.R2.close()
     if self.R3: self.R3.close()
     if self.R2C: self.R2C.close()
     if self.R3C: self.R3C.close()
     return
示例#21
0
 def endWatch(self, handler, evtype=None):
     """
     Terminate request to receive notice of subscribe/unsubscribe events for 
     a given event type.
     """
     Trace("%s endWatch %s from %s"%(self.getUri(), evtype, str(handler)), 
           context="EventLib.EventPubSub")
     return self.unsubscribe(handler, evtype=URI.EventSubscribeType, source=evtype)
示例#22
0
 def testWatchPrior4(self):
     Trace("testWatchPrior4","TestEventPubSub")
     self.setUpRouter()
     h1 = MyEventHandler("H1")
     w1 = MyEventHandler("W1")
     self.router.subscribe(60, h1)
     self.router.watch(5, w1)
     assert w1.isWatched(),"Watch * not triggered for prior wildcard subscribe"
示例#23
0
 def syncValue(self):
     """
     Wait for value to be available, then return it
     """
     Trace("QueueDeferred.syncValue (%s)"%(str(self._value)), context="EventLib.QueueDeferred")
     self._event.clear()
     if not self._queue.empty():
         self._event.wait(timeout=20)        # Timeout is precaution to prevent total lockout
     return self._value
示例#24
0
 def close_request(self, request):
     """
     Override close_request to deal with None request at closedown
     """
     Trace("%s close_request %s" % (self._relay.getUri(), str(request)),
           "EventLib.EventRelayHTTPS")
     if request:
         # super(EventRequestServer, self).close_request(request)
         HTTPServer.close_request(self, request)
示例#25
0
 def __init__(self, uri=None):
     """
     Initialize a new EventPubSub object
     """
     if not uri: uri = "(EventPubSub %u)"%(id(self))
     Trace("%s Init"%(uri), context="EventLib.EventPubSub")
     super(EventPubSub, self).__init__(uri)
     # Subscription table for local delivery of events
     self._sub        = EventTypeSourceDict()
     self._subcount   = 0
     return
示例#26
0
 def queueItem(self, item):
     """
     Add item to the queue, and return a deferred object that fires when an item is removed
     (or the queue is empty).
     """
     Trace("%s queueItem (%s)" % (self.getUri(), item),
           "EventLib.EventRelayHTTPC")
     if not self._closing:
         self._queue.put(item)
         return makeQueueDeferred(StatusVal.OK, self._queue, self._event)
     return makeDeferred(StatusVal.OK)
示例#27
0
 def testWatch6(self):
     Trace("testWatch6","TestEventPubSub")
     self.setUpRouter()
     h1 = MyEventHandler("H1")
     w1 = MyEventHandler("W1")
     self.router.watch(5, w1)
     w1.resetWatched()
     self.router.subscribe(60, h1, evtype="t1", source="s1")
     assert w1.isWatched(),"Watch * not triggered on subscribe"
     w1.resetWatched()
     self.router.unsubscribe(h1, evtype="t1", source="s1")
     assert w1.isWatched(),"Watch * not triggered on unsubscribe"
示例#28
0
 def testWatch7(self):
     Trace("testWatch7","TestEventPubSub")
     self.setUpRouter()
     h1 = MyEventHandler("H1")
     w1 = MyEventHandler("W1")
     self.router.watch(5, w1)
     w1.resetWatched()
     self.router.subscribe(60, h1)
     assert w1.isWatched(),"Watch * not triggered on wild subscribe"
     w1.resetWatched()
     self.router.unsubscribe(h1)
     assert w1.isWatched(),"Watch * not triggered on wild unsubscribe"
示例#29
0
 def testWatch2(self):
     Trace("testWatch2","TestEventPubSub")
     self.setUpRouter()
     w1 = MyEventHandler("W1")
     w2 = MyEventHandler("W2")
     self.router.watch(5, w1, evtype="t1")
     self.router.watch(5, w2, evtype="t2")
     w1.resetWatched()
     w2.resetWatched()
     self.router.subscribe(60, self.handlers[0], evtype="t2")
     assert not w1.isWatched(), "Watch t1 triggered on subscribe"
     assert w2.isWatched(), "Watch t2 not triggered on subscribe"
示例#30
0
 def setUpRouter(self):
     Trace("setUp","TestEventPubSub")
     a = MyEventHandler("A")
     b = MyEventHandler("B")
     c = MyEventHandler("C")
     d = MyEventHandler("D")
     e = MyEventHandler("E")
     f = MyEventHandler("F")
     g = MyEventHandler("G")
     h = MyEventHandler("H")
     self.handlers = (a, b, c, d, e, f, g, h)
     self.router   = EventPubSub(uri="LocalRouter")
     self.router.subscribe(60, a, evtype="t1", source="s1")
     self.router.subscribe(60, b, evtype="t2", source="s1")
     self.router.subscribe(60, c, evtype="t1", source="s2")
     self.router.subscribe(60, d, evtype="t2", source="s2")
     self.router.subscribe(60, e, evtype="t1")
     self.router.subscribe(60, f, evtype="", source="s1")
     self.router.subscribe(60, g, source="")
     self.router.subscribe(60, h, evtype="t2", source="s1")  # same as b
     Trace("setUp exit","TestEventPubSub")
     return