Exemplo n.º 1
0
class Listener(Thread):

    '''PyTroll listener class for reading messages for Trollduction
    '''

    def __init__(self, address, topics, callback, *args, **kwargs):
        '''Init Listener object
        '''
        super(Listener, self).__init__()

        self.topics = topics
        self.callback = callback
        self.subscriber = None
        self.address = address
        self.create_subscriber()
        self.running = False
        self.cargs = args
        self.ckwargs = kwargs

    def create_subscriber(self):
        '''Create a subscriber instance using specified addresses and
        message types.
        '''
        if self.subscriber is None:
            if self.topics:
                LOGGER.info("Subscribing to %s with topics %s", str(self.address), str(self.topics))
                self.subscriber = Subscriber(self.address, self.topics)

    def run(self):
        '''Run listener
        '''

        self.running = True

        for msg in self.subscriber(timeout=1):
            if msg is None:
                if self.running:
                    continue
                else:
                    break
            self.callback(msg, *self.cargs, **self.ckwargs)

        LOGGER.debug("exiting listener %s", str(self.address))

    def stop(self):
        '''Stop subscriber and delete the instance
        '''
        self.running = False
        time.sleep(1)
        if self.subscriber is not None:
            self.subscriber.close()
            self.subscriber = None
Exemplo n.º 2
0
class Listener(object):
    '''PyTroll listener class for reading messages for Trollduction
    '''

    def __init__(self, address_list=None, msg_type_list=None,
                 ip=None, port=None, pipe=None):
        '''Init Listener object
        '''
        self.address_list = []
        self.add_address_list(address_list)
        self.add_address(ip, port)
        self.msg_type_list = []
        if msg_type_list is not None:
            self.msg_type_list = msg_type_list
        self.deque = deque()
        self.pipe = pipe
        self.subscriber = None
        self.create_subscriber()
        self.running = False
        

    def add_address(self, ip, port):
        '''Add address that will be listened
        '''
        if ip is not None and port is not None:
            self.address_list.append('tcp://'+ip+':%04d' % port)


    def add_address_list(self, address_list):
        '''Add a list of addresses that will be listened
        '''
        for address in address_list:
            self.address_list.append(address)


    def create_subscriber(self):
        '''Create a subscriber instance using specified addresses and
        message types.
        '''
        if self.subscriber is None:
            if len(self.address_list) > 0:
                if len(self.msg_type_list) > 0:
                    self.subscriber = Subscriber(self.address_list, 
                                                 *self.msg_type_list)

    def send_to_pipe(self, msg):
        '''Send message to parent via a Pipe()
        '''
        self.pipe.send(msg)


    def run(self):
        '''Run listener
        '''

        # TODO: add logging

        print "Starting Listener"

        self.running = True

        for msg in self.subscriber.recv():
            print "New message received"
            if msg.subject == '/stop_listener':
                break
            if self.pipe is None:
                self.deque.append(msg)
            else:
                while len(self.deque) > 0:
                    self.send_to_pipe(self.deque.popleft())
            self.send_to_pipe(msg)
            

    def stop(self):
        '''Stop subscriber and delete the instance
        '''
        
        # TODO: add logging
        
        self.subscriber.stop()
        self.subscriber.close()
        self.subscriber = None
        self.running = False


    def restart(self):
        '''Restart subscriber
        '''
        self.stop()
        self.create_subscriber()
        self.run()
Exemplo n.º 3
0
class Listener(Thread):
    '''PyTroll listener class for reading messages for Trollduction
    '''
    def __init__(self, address, topics, callback, *args, **kwargs):
        '''Init Listener object
        '''
        super(Listener, self).__init__()

        self.topics = topics
        self.callback = callback
        self.subscriber = None
        self.address = address
        self.running = False
        self.cargs = args
        self.ckwargs = kwargs
        self.restart_event = Event()

    def create_subscriber(self):
        '''Create a subscriber instance using specified addresses and
        message types.
        '''
        if self.subscriber is None:
            if self.topics:
                LOGGER.info("Subscribing to %s with topics %s",
                            str(self.address), str(self.topics))
                self.subscriber = Subscriber(self.address, self.topics)
                LOGGER.debug("Subscriber %s", str(self.subscriber))

    def run(self):
        '''Run listener
        '''

        with heartbeat_monitor.Monitor(self.restart_event,
                                       **self.ckwargs) as beat_monitor:

            self.running = True

            while self.running:
                # Loop for restart.

                LOGGER.debug("Starting listener %s", str(self.address))
                self.create_subscriber()

                for msg in self.subscriber(timeout=1):
                    if not self.running:
                        break

                    if self.restart_event.is_set():
                        self.restart_event.clear()
                        self.stop()
                        self.running = True
                        break

                    if msg is None:
                        continue

                    LOGGER.debug("Receiving (SUB) %s", str(msg))

                    beat_monitor(msg)
                    if msg.type == "beat":
                        continue

                    self.callback(msg, *self.cargs, **self.ckwargs)

                LOGGER.debug("Exiting listener %s", str(self.address))

    def stop(self):
        '''Stop subscriber and delete the instance
        '''
        self.running = False
        time.sleep(1)
        if self.subscriber is not None:
            self.subscriber.close()
            self.subscriber = None
Exemplo n.º 4
0
class Listener(object):
    '''PyTroll listener class for reading messages for Trollduction
    '''
    def __init__(self,
                 address_list=None,
                 msg_type_list=None,
                 ip=None,
                 port=None,
                 pipe=None):
        '''Init Listener object
        '''
        self.address_list = []
        self.add_address_list(address_list)
        self.add_address(ip, port)
        self.msg_type_list = []
        if msg_type_list is not None:
            self.msg_type_list = msg_type_list
        self.deque = deque()
        self.pipe = pipe
        self.subscriber = None
        self.create_subscriber()
        self.running = False

    def add_address(self, ip, port):
        '''Add address that will be listened
        '''
        if ip is not None and port is not None:
            self.address_list.append('tcp://' + ip + ':%04d' % port)

    def add_address_list(self, address_list):
        '''Add a list of addresses that will be listened
        '''
        for address in address_list:
            self.address_list.append(address)

    def create_subscriber(self):
        '''Create a subscriber instance using specified addresses and
        message types.
        '''
        if self.subscriber is None:
            if len(self.address_list) > 0:
                if len(self.msg_type_list) > 0:
                    self.subscriber = Subscriber(self.address_list,
                                                 *self.msg_type_list)

    def send_to_pipe(self, msg):
        '''Send message to parent via a Pipe()
        '''
        self.pipe.send(msg)

    def run(self):
        '''Run listener
        '''

        # TODO: add logging

        print "Starting Listener"

        self.running = True

        for msg in self.subscriber.recv():
            print "New message received"
            if msg.subject == '/stop_listener':
                break
            if self.pipe is None:
                self.deque.append(msg)
            else:
                while len(self.deque) > 0:
                    self.send_to_pipe(self.deque.popleft())
            self.send_to_pipe(msg)

    def stop(self):
        '''Stop subscriber and delete the instance
        '''

        # TODO: add logging

        self.subscriber.stop()
        self.subscriber.close()
        self.subscriber = None
        self.running = False

    def restart(self):
        '''Restart subscriber
        '''
        self.stop()
        self.create_subscriber()
        self.run()
Exemplo n.º 5
0
class Listener(Thread):
    """PyTroll listener class for reading messages for Trollduction."""
    def __init__(self, address, topics, callback, *args, **kwargs):
        """Init Listener object."""
        super(Listener, self).__init__()

        self.topics = topics
        self.callback = callback
        self.subscriber = None
        self.address = address
        self.running = False
        self.cargs = args
        self.ckwargs = kwargs
        self.restart_event = Event()

    def create_subscriber(self):
        """Create a subscriber using specified addresses and message types."""
        if self.subscriber is None:
            if self.topics:
                LOGGER.info("Subscribing to %s with topics %s",
                            str(self.address), str(self.topics))
                self.subscriber = Subscriber(self.address, self.topics)
                LOGGER.debug("Subscriber %s", str(self.subscriber))

    def run(self):
        """Run listener."""
        with heartbeat_monitor.Monitor(self.restart_event,
                                       **self.ckwargs) as beat_monitor:

            self.running = True

            while self.running:
                # Loop for restart.

                LOGGER.debug("Starting listener %s", str(self.address))
                self.create_subscriber()

                for msg in self.subscriber(timeout=1):
                    if not self.running:
                        break

                    if self.restart_event.is_set():
                        self.restart_event.clear()
                        self.stop()
                        self.running = True
                        break

                    if msg is None:
                        continue

                    LOGGER.debug("Receiving (SUB) %s", str(msg))

                    beat_monitor(msg)
                    if msg.type == "beat":
                        continue
                    # Handle public "push" messages as a hot spare client
                    if msg.type == "push":
                        # TODO: these need to be checked and acted if
                        # the transfers are not finished on primary
                        # client and are not cleared
                        LOGGER.debug("Primary client published 'push'")
                        add_to_ongoing(msg)

                    # Handle public "ack" messages as a hot spare client
                    if msg.type == "ack":
                        LOGGER.debug("Primary client finished transfer")
                        _ = add_to_file_cache(msg)
                        _ = clean_ongoing_transfer(get_msg_uid(msg))

                    # If this is a hot spare client, wait for a while
                    # for a public "push" message which will update
                    # the ongoing transfers before starting processing here
                    delay = self.ckwargs.get("processing_delay", False)
                    if delay:
                        add_timer(float(delay), self.callback, msg,
                                  *self.cargs, **self.ckwargs)
                    else:
                        self.callback(msg, *self.cargs, **self.ckwargs)

                LOGGER.debug("Exiting listener %s", str(self.address))

    def stop(self):
        """Stop subscriber and delete the instance."""
        self.running = False
        time.sleep(1)
        if self.subscriber is not None:
            self.subscriber.close()
            self.subscriber = None
Exemplo n.º 6
0
class Listener(Thread):
    """PyTroll listener class for reading messages for Trollduction."""
    def __init__(self, address, topics, *args, die_event=None, **kwargs):
        """Init Listener object."""
        super(Listener, self).__init__()

        self.topics = topics
        self.subscriber = None
        self.address = address
        self.running = False
        self.die_event = die_event
        self.cargs = args
        self.ckwargs = kwargs
        self.restart_event = Event()
        self.cause_of_death = None
        self.death_count = 0

    def restart(self):
        """Restart the listener, returns a new running instance."""
        self.stop()
        new_listener = self.__class__(self.address,
                                      self.topics,
                                      *self.cargs,
                                      die_event=self.die_event,
                                      **self.ckwargs)
        new_listener.death_count = self.death_count + 1
        new_listener.start()
        return new_listener

    def create_subscriber(self):
        """Create a subscriber using specified addresses and message types."""
        if self.subscriber is None:
            if self.topics:
                LOGGER.info("Subscribing to %s with topics %s",
                            str(self.address), str(self.topics))
                self.subscriber = Subscriber(self.address, self.topics)
                LOGGER.debug("Subscriber %s", str(self.subscriber))

    def run(self):
        """Run listener."""
        try:
            with heartbeat_monitor.Monitor(self.restart_event,
                                           **self.ckwargs) as beat_monitor:
                self.running = True
                while self.running:
                    LOGGER.debug("Starting listener %s", str(self.address))
                    self.create_subscriber()
                    self._get_messages(beat_monitor)
        except Exception as err:
            LOGGER.exception("Listener died.")
            self.cause_of_death = err
            with suppress(AttributeError):
                self.die_event.set()

    def _get_messages(self, beat_monitor):
        for msg in self.subscriber(timeout=1):
            if not self.running:
                break
            if not self._check_heartbeat():
                break
            if msg is None:
                continue

            LOGGER.debug("Receiving (SUB) %s", str(msg))

            beat_monitor(msg)

            if self._is_message_already_handled(msg):
                continue

            self._process_message(msg)

        LOGGER.debug("Exiting listener %s", str(self.address))

    def _check_heartbeat(self):
        if self.restart_event.is_set():
            LOGGER.warning(
                "Missing a heartbeat, restarting the subscriber to %s.",
                str(self.subscriber.addresses))
            self.restart_event.clear()
            self.stop()
            self.running = True
            return False
        return True

    def _is_message_already_handled(self, msg):
        return (self._handle_beat_message(msg) or _handle_push_message(msg)
                or _handle_ack_message(msg)
                or _handle_message_from_another_client(msg))

    def _handle_beat_message(self, msg):
        if msg.type == "beat":
            self.death_count = 0
            return True
        return False

    def _process_message(self, msg):
        delay = self.ckwargs.get("processing_delay", False)
        if delay:
            # If this is a hot spare client, wait for a while
            # for a public "push" message which will update
            # the ongoing transfers before starting processing here
            add_request_push_timer(float(delay), msg, *self.cargs,
                                   **self.ckwargs)
        else:
            request_push(msg, *self.cargs, **self.ckwargs)

    def stop(self):
        """Stop subscriber and delete the instance."""
        self.running = False
        time.sleep(1)
        if self.subscriber is not None:
            self.subscriber.close()
            self.subscriber = None