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()
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()
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
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)
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)
def publish(self, topic, body): p = Producer() t = Topic(topic) sn = p.send(t, **body) return sn