Example #1
0
 def append_health_check_function(self, func_name, retry_period=5000):
     from inspect import signature
     if signature(func_name).return_annotation is not bool:
         raise TypeError(f"{func_name} must return a boolean")
     self._health_check_functions.append(
         {'func': func_name, 'retry_period': retry_period, 'last_check': datetime.now() - timedelta(days=1)})
     if self.default_health_check_period > retry_period:
         self.health_check_period = retry_period
         logger.debug(f"New health check interval: {retry_period}")
Example #2
0
 def _publish(self, message, topic):
     properties = pika.BasicProperties(
         content_type='application/json', priority=0, delivery_mode=2,
         content_encoding="utf-8")
     logger.debug(f"Trying send message{message}")
     self._channel.basic_publish(exchange=topic,
                                 routing_key="",
                                 body=json.dumps(message, indent=4, sort_keys=True, default=str).encode(),
                                 properties=properties)
     logger.debug('message sent: %s', message)
Example #3
0
 def declare_topic(self, topic_name):
     try:
         if self._channel is None:
             self.connect()
         self._declare_topic(topic_name)
     except (pika.exceptions.ChannelWrongStateError, pika.exceptions.ConnectionClosed, pika.exceptions.ChannelClosed,
             pika.exceptions.ChannelClosedByBroker,pika.exceptions.ConnectionWrongStateError, pika.exceptions.StreamLostError):
         logger.debug('reconnecting to rabbit')
         self.connect()
         self._declare_topic(topic_name)
Example #4
0
    def send_message(self, message, topic):

        logger.debug(f"Insert data on TOPIC: {topic}")

        if not topic.startswith(self.config.get_event_name_prefix()):
            topic = f"{self.config.get_event_name_prefix()}{topic}"

        try:
            self._publish(message, topic)
        except (pika.exceptions.ChannelWrongStateError, pika.exceptions.ConnectionClosed, pika.exceptions.ChannelClosed,
                pika.exceptions.ChannelClosedByBroker, pika.exceptions.ConnectionWrongStateError, pika.exceptions.StreamLostError):
            logger.debug('reconnecting to queue')
            self.connect()
            self._publish(message, topic)
Example #5
0
 def process_next_message(self,
                          queue_name,
                          callback,
                          model_validator,
                          max_retry=0):
     sub_queue = self.get_simple_queue(queue_name)
     retry_count = 0
     while True:
         try:
             msg = sub_queue.get(block=False, timeout=20)
             try:
                 e = Event(**msg.payload)
             except ValueError as ve:
                 logger.error(
                     f"Rejecting not valid event payload: {msg.payload}")
                 msg.ack()
                 return True
             try:
                 if model_validator is not None:
                     try:
                         call_result = callback(
                             e, model_validator(**e.payload))
                     except Exception as error:
                         logger.error(
                             f"Invalid payload for type.  Errors: {str(error)}"
                         )
                         msg.ack()
                         return True
                 else:
                     call_result = callback(e)
                 if call_result:
                     msg.ack()
                     return True
                 else:
                     logger.debug("Callback returning false")
                     msg.requeue()
                     return False
             except:
                 msg.requeue()
                 return False
         except IOError:
             logger.error("Lost connection with Rabbit")
             self.queues = {}
             return False
         except Empty as e:
             if retry_count < max_retry:
                 sleep(0.1)
                 retry_count += 1
             else:
                 return True
Example #6
0
    def send_message(self, message, topic):
        # with self.send_connection as _conn:
        _conn = self.send_connection
        _conn.connect()
        # channel = _conn.channel()
        with _conn.channel() as channel:
            producer = Producer(channel)

            logger.debug(f"Insert data on TOPIC: {topic}")

            if not topic.startswith(self.config.get_event_name_prefix()):
                topic = f"{self.config.get_event_name_prefix()}{topic}"

            producer.publish(body=message, exchange=topic, routing_key=None)

            logger.debug(f"Message {message} sent to topic {topic}!")
Example #7
0
 def health_checks(self):
     previous_status = self.can_execute
     for check in self._health_check_functions:
         current_millis = datetime.now()
         if (current_millis - check['last_check']).total_seconds() * 1000 >= check['retry_period']:
             [x for x in self._health_check_functions if x['func'] == check['func']][0][
                 'last_check'] = current_millis
             if not check['func']():
                 self.can_execute = 1
                 self.health_check_period = check["retry_period"]
                 msg = f'Health check {check["func"].__name__} return False. Stop consuming for {check["retry_period"] / 1000} seconds.'
                 if previous_status < 1:
                     logger.info(msg)
                 else:
                     logger.debug(msg)
                 return
     if self.can_execute > 0:
         self.can_execute = 0
         self.health_check_period = self.default_health_check_period
         logger.info("Resuming consuming...")
Example #8
0
    def start_listening(self):
        try:
            logger.info("Starting consumer...")
            while True:
                current_millis = datetime.now()
                if (current_millis - self.last_health_check).total_seconds() * 1000 >= self.health_check_period:
                    logger.debug("Health check time...")
                    self.health_checks()
                    self.last_health_check = datetime.now()
                try:
                    if self.can_execute < 1:
                        self.can_execute = self.check_events()
                        if self.can_execute > 0:
                            logger.error("Something happened on run... stop consuming")

                    sleep(0.02)
                except Exception as err:
                    self.can_execute = 2
                    self.health_check_period = self.health_check_period_on_critical_error
                    logger.critical(str(err))

        except KeyboardInterrupt:
            logger.debug('interrupted!')
Example #9
0
 def disconnect(self):
     if self._conn and self._conn.is_open:
         logger.debug('closing queue connection')
         self._conn.close()