Ejemplo n.º 1
0
 def accepted(self, sock):
     uuid = toq(getuuid())
     p = Producer(url=self.url)
     p.send(toq(self.peer), peer=str(uuid))
     r = Reader(uuid, url=self.url)
     env = r.next()
     tr = TunnelReader(r, sock)
     tr.start()
     tw = TunnelWriter(self.url, env.peer, sock)
     tw.start()
Ejemplo n.º 2
0
 def dispatch(self, env):
     peer = env.peer
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.connect((self.host, self.port))
     uuid = toq(getuuid())
     p = Producer(url=self.url)
     p.send(env.peer, peer=str(uuid))
     reader = Reader(uuid, url=self.url)
     tr = TunnelReader(reader, sock)
     tr.start()
     tw = TunnelWriter(self.url, env.peer, sock)
     tw.start()
Ejemplo n.º 3
0
 def producer(cls):
     """
     Get the cached producer.
     :return: A producer.
     :rtype: Producer
     """
     if not cls.__producer:
         broker = plugin.getbroker()
         url = str(broker.url)
         cls.__producer = Producer(url=url)
     return cls.__producer
Ejemplo n.º 4
0
 def process(self):
     """
     Process all I{outstanding} journal entries.
     When a journal entry (timeout) is detected, a L{RequestTimeout}
     exception is raised and sent to the I{replyto} AMQP address.
     The journal entry is deleted.
     """
     sent = []
     now = time()
     if self.__producer is None:
         self.__producer = Producer(url=self.url)
     for sn,je in self.__jnl.load().items():
         if now > je.ts[je.idx]:
             sent.append(sn)
             try:
                 raise RequestTimeout(sn, je.idx)
             except:
                 self.__overdue(je)
     for sn in sent:
         self.__jnl.delete(sn)
Ejemplo n.º 5
0
class WatchDog:
    """
    A watchdog object used to track asynchronous messages
    by serial number.  Tracking is persisted using journal files.
    @ivar url: The AMQP broker URL.
    @type url: str
    @ivar __jnl: A journal use for persistence.
    @type __jnl: L{Journal}
    @ivar __producer: An AMQP message producer.
    @type __producer: L{Producer}
    @ivar __run: Run flag.
    @type __run: bool
    """
    
    __metaclass__ = Singleton
 
    URL = Producer.LOCALHOST

    def __init__(self, url=URL, journal=None):
        """
        @param url: The (optional) broker URL.
        @type url: str
        @param journal: A journal object (default: Journal()).
        @type journal: L{Journal}
        """
        self.url = url
        self.__producer = None
        self.__jnl = (journal or Journal())

    def start(self):
        """
        Start a watchdog thread.
        @return: The started thread.
        @rtype: L{WatchDogThread}
        """
        thread = WatchDogThread(self)
        thread.start()
        return thread
    
    def track(self, sn, replyto, any, timeout):
        """
        Add a request by serial number for tacking.
        @param sn: A serial number.
        @type sn: str
        @param replyto: An AMQP address.
        @type replyto: str
        @param any: User defined data.
        @type any: any
        @param timeout: A timeout (start,complete)
        @type timeout: tuple(2)
        """
        now = time()
        ts = (now+timeout[0], now+timeout[1])
        je = self.__jnl.write(sn, replyto, any, ts)
        log.info('tracking: %s', je)
            
    def started(self, sn):
        """
        Timeout is a tuple of: (start,complete).
        A proper status='started' has been received and the timout
        index is changed from 0 to 1.  This switches the timeout logic
        to work off the 2nd timeout which indicates the completion timeout.
        @param sn: An entry serial number.
        @type sn: str
        """
        log.info(sn)
        je = self.__jnl.find(sn)
        if je:
            self.__jnl.update(sn, idx=1)
        else:
            pass # ignored
        
    def progress(self, sn):
        """
        Progress reporting received.
        Because a progress report has been received, the
        current timestamp is bumped 5 seconds only if the timestamp
        is within 5 seconds of expiration.
        """
        log.info(sn)
        je = self.__jnl.find(sn)
        if not je:
            # ignored
            return
        if je.idx != 1:
            # invalid state
            return
        grace_period = time()+5 # seconds
        if grace_period > je.ts[1]:
            ts = (je.ts[0], grace_period)
            self.__jnl.update(sn, ts=ts)
        
    def completed(self, sn):
        """
        The request has been properly completed by the agent.
        Tracking is discontinued.
        @param sn: An entry serial number.
        @type sn: str
        """
        log.info(sn)
        self.__jnl.delete(sn)

    def process(self):
        """
        Process all I{outstanding} journal entries.
        When a journal entry (timeout) is detected, a L{RequestTimeout}
        exception is raised and sent to the I{replyto} AMQP address.
        The journal entry is deleted.
        """
        sent = []
        now = time()
        if self.__producer is None:
            self.__producer = Producer(url=self.url)
        for sn,je in self.__jnl.load().items():
            if now > je.ts[je.idx]:
                sent.append(sn)
                try:
                    raise RequestTimeout(sn, je.idx)
                except:
                    self.__overdue(je)
        for sn in sent:
            self.__jnl.delete(sn)
    
    def __overdue(self, je):
        """
        Send the (timeout) reply to the I{replyto} AMQP address
        specified in the journal entry.
        @param je: A journal entry.
        @type je: Entry
        """
        log.info('sn:%s timeout detected', je.sn)
        try:
            self.__sendreply(je)
        except:
            log.exception(str(je))
        
    def __sendreply(self, je):
        """
        Send the (timeout) reply to the I{replyto} AMQP address
        specified in the journal entry.
        @param je: A journal entry.
        @type je: Entry
        """
        sn = je.sn
        replyto = je.replyto
        any = je.any
        result = Return.exception()
        log.info('send (timeout) for sn:%s to:%s', sn, replyto)
        self.__producer.send(
            replyto,
            sn=sn,
            any=any,
            result=result,
            watchdog=self.__producer.uuid)
Ejemplo n.º 6
0
 def publish(self, topic, body):
     p = Producer()
     t = Topic(topic)
     sn = p.send(t, **body)
     return sn