Пример #1
0
    def __tell_publisher_to_stop_waiting_for_gentle_finish(self):
        logdebug(LOGGER, 'Main thread does not need to wait anymore. (%s).', get_now_utc_as_formatted_string())

        # This avoids that the last iteration is redone
        # and redone upon reconnection, as after reconnection,
        # if this is True, the algorithm is entered again.
        self.__is_in_process_of_gently_closing = False

        # This releases the event that blocks the main thread
        # until the gentle finish is done.
        self.thread.tell_publisher_to_stop_waiting_for_gentle_finish()
Пример #2
0
 def __please_open_connection(self):
     params = self.__node_manager.get_connection_parameters()
     self.__start_connect_time = datetime.datetime.now()
     logdebug(LOGGER, 'Connecting to RabbitMQ at %s... (%s)', params.host,
              get_now_utc_as_formatted_string())
     loginfo(LOGGER, 'Opening connection to RabbitMQ...')
     self.thread._connection = pika.SelectConnection(
         parameters=params,
         on_open_callback=self.on_connection_open,
         on_open_error_callback=self.on_connection_error,
         on_close_callback=self.on_connection_closed,
         stop_ioloop_on_close=False  # why? see below. 
     )
Пример #3
0
 def __please_open_connection(self):
     params = self.__node_manager.get_connection_parameters()
     self.__start_connect_time = datetime.datetime.now()
     logdebug(LOGGER, 'Connecting to RabbitMQ at %s... (%s)', params.host,
              get_now_utc_as_formatted_string())
     loginfo(LOGGER, 'Opening connection to RabbitMQ...')
     self.thread._connection = pika.SelectConnection(
         parameters=params,
         on_open_callback=self.on_connection_open,
         on_open_error_callback=self.on_connection_error,
         on_close_callback=self.on_connection_closed
         # Removed parameter, see https://github.com/pika/pika/issues/961
     )
Пример #4
0
    def __finish_gently(self):
        # Called directly from outside the thread!

        # No more messages can arrive from publisher (because
        # the main thread blocks), but publishes/confirms are still
        # accepted.

        # Inform user
        if self.__are_any_messages_pending():
            wait_seconds = defaults.RABBIT_ASYN_FINISH_WAIT_SECONDS
            max_waits = defaults.RABBIT_ASYN_FINISH_MAX_TRIES
            loginfo(
                LOGGER,
                'Preparing to close PID module. Some messages are pending. Maximum waiting time: %i seconds. (%s)',
                wait_seconds * max_waits, get_now_utc_as_formatted_string())
        else:
            loginfo(LOGGER, 'Closing PID module. No pending messages. (%s)',
                    get_now_utc_as_formatted_string())

        # Go through decision tree (close or wait for pending messages)
        self.__close_decision_iterations = 1
        self.__is_in_process_of_gently_closing = True
        self.recursive_decision_about_closing()
Пример #5
0
    def on_connection_open(self, unused_connection):
        logdebug(LOGGER, 'Opening connection... done.')
        loginfo(LOGGER, 'Connection to RabbitMQ at %s opened... (%s)',
                self.__node_manager.get_connection_parameters().host,
                get_now_utc_as_formatted_string())

        # Tell the main thread we're open for events now:
        # When the connection is open, the thread is ready to accept events.
        # Note: It was already ready when the connection object was created,
        # not just now that it's actually open. There was already a call to
        # "...stop_waiting..." in start_waiting_for_events(), which quite
        # certainly was carried out before this callback. So this call to
        # "...stop_waiting..." is likelily redundant!
        self.thread.tell_publisher_to_stop_waiting_for_thread_to_accept_events(
        )
        self.__please_open_rabbit_channel()
Пример #6
0
 def make_permanently_closed_by_user(self):
     # This changes the state of the state machine!
     # This needs to be called from the shutter module
     # in case there is a force_finish while the connection
     # is already closed (as the callback on_connection_closed
     # is not called then).
     self.statemachine.set_to_permanently_unavailable()
     logtrace(LOGGER, 'Stop waiting for events due to user interrupt!')
     logtrace(LOGGER,
              'Permanent close: Stopping ioloop of connection %s...',
              self.thread._connection)
     self.thread._connection.ioloop.stop()
     loginfo(LOGGER, 'Stopped listening for RabbitMQ events (%s).',
             get_now_utc_as_formatted_string())
     logdebug(
         LOGGER,
         'Connection to messaging service closed by user. Will not reopen.')
Пример #7
0
    def __finish_gently(self):
        # Called directly from outside the thread!
        #self.statemachine.asked_to_closed_by_publisher = True # TODO

        # Make sure no more messages are accepted from publisher # TODO
        # while publishes/confirms are still accepted:
        #if self.statemachine.is_available_for_client_publishes():
        #    self.statemachine.set_to_wanting_to_stop()

        # Inform user
        if self.__are_any_messages_pending():
            wait_seconds = defaults.RABBIT_ASYN_FINISH_WAIT_SECONDS
            max_waits = defaults.RABBIT_ASYN_FINISH_MAX_TRIES
            loginfo(LOGGER, 'Preparing to close PID module. Some messages are pending. Maximum waiting time: %i seconds. (%s)', wait_seconds*max_waits, get_now_utc_as_formatted_string())
        else:
            loginfo(LOGGER, 'Closing PID module. No pending messages. (%s)', get_now_utc_as_formatted_string())

        # Go through decision tree (close or wait for pending messages)
        self.__close_decision_iterations = 1
        self.__is_in_process_of_gently_closing = True
        self.recursive_decision_about_closing()
Пример #8
0
    def make_permanently_closed_by_error(self, connection, reply_text):
        # This changes the state of the state machine!
        # This needs to be called if there is a permanent
        # error and we don't want the library to reonnect,
        # and we also don't want to pretend it was closed
        # by the user.
        # This is really rarely needed.
        self.statemachine.set_to_permanently_unavailable()
        logtrace(LOGGER, 'Stop waiting for events due to permanent error!')

        # In case the main thread was waiting for any synchronization event.
        self.thread.unblock_events()

        # Close ioloop, which blocks the thread.
        logdebug(LOGGER,
                 'Permanent close: Stopping ioloop of connection %s...',
                 self.thread._connection)
        self.thread._connection.ioloop.stop()
        loginfo(LOGGER, 'Stopped listening for RabbitMQ events (%s).',
                get_now_utc_as_formatted_string())
        logdebug(
            LOGGER,
            'Connection to messaging service closed because of error. Will not reopen. Reason: %s',
            reply_text)
Пример #9
0
 def __define_other_attributes(self):
     self.__dataset_handle = None
     self.__list_of_file_handles = []
     self.__list_of_file_messages = []
     self.__message_timestamp = utils.get_now_utc_as_formatted_string()
Пример #10
0
    def __setup_rabbit_connection(self, params):
        LOGGER.debug('Setting up the connection with the RabbitMQ.')
        self.__start_connect_time = datetime.datetime.now()
        self.__all_hosts_that_were_tried.add(params.host)

        try:
            time_now = get_now_utc_as_formatted_string()
            logdebug(LOGGER, 'Connecting to RabbitMQ at %s... (%s)',
                     params.host, time_now)

            # Make connection
            conn = self.__make_connection(params)

            # Log success
            time_now = get_now_utc_as_formatted_string()
            time_passed = datetime.datetime.now() - self.__start_connect_time
            time_seconds = time_passed.total_seconds()
            loginfo(
                LOGGER,
                'Connection to RabbitMQ at %s opened after %i seconds... (%s)',
                params.host, time_seconds, time_now)
            return conn

        except pika.exceptions.ProbableAuthenticationError as e:
            time_passed = datetime.datetime.now() - self.__start_connect_time
            time_seconds = time_passed.total_seconds()
            error_name = e.__class__.__name__
            logerror(
                LOGGER,
                'Caught Authentication Exception after %s seconds during connection ("%s").',
                time_seconds, error_name)
            msg = (
                'Problem setting up the rabbit with username "%s" and password "%s" at url %s.'
                % (params.credentials.username, params.credentials.password,
                   params.host))
            LOGGER.error(msg)
            self.__error_messages_during_init.append(msg)
            return None

        except pika.exceptions.AMQPConnectionError as e:
            time_passed = datetime.datetime.now() - self.__start_connect_time
            time_seconds = time_passed.total_seconds()
            error_name = e.__class__.__name__
            logerror(
                LOGGER,
                'Caught AMQPConnectionError Exception after %s seconds during connection ("%s").',
                time_seconds, error_name)
            msg = ('Problem setting up the rabbit connection to %s.' %
                   params.host)
            self.__error_messages_during_init.append(msg)
            return None

        except Exception as e:
            time_passed = datetime.datetime.now() - self.__start_connect_time
            time_seconds = time_passed.total_seconds()
            error_name = e.__class__.__name__
            logerror(
                LOGGER,
                'Error ("%s") during connection to %s, after %s seconds.',
                error_name, params.host, time_seconds)
            msg = (
                'Unexpected problem setting up the rabbit connection to %s (%s)'
                % (params.host, error_name))
            self.__error_messages_during_init.append(msg)
            raise e