Example #1
0
 def _handler_runner_callback(completed_future):
     try:
         e = completed_future.exception(timeout=0)
     except Exception as raised_e:
         # This shouldn't happen because cancellation or timeout shouldn't occur...
         # But just in case...
         new_err = HandlerManagerException(
             message="HANDLER RUNNER ({}): Unable to retrieve exception data from incomplete task".format(
                 handler_name
             ),
             cause=raised_e,
         )
         handle_exceptions.handle_background_exception(new_err)
     else:
         if e:
             # If this branch is reached something has gone SERIOUSLY wrong.
             # We must log the error, and then restart the runner so that the program
             # does not enter an invalid state
             new_err = HandlerManagerException(
                 message="HANDLER RUNNER ({}): Unexpected error during task".format(
                     handler_name
                 ),
                 cause=e,
             )
             handle_exceptions.handle_background_exception(new_err)
             # Clear the tracked runner, and start a new one
             self._handler_runners[handler_name] = None
             self._start_handler_runner(handler_name)
         else:
             logger.debug(
                 "HANDLER RUNNER ({}): Task successfully completed without exception".format(
                     handler_name
                 )
             )
Example #2
0
 def _handler_callback(future):
     try:
         e = future.exception(timeout=0)
     except Exception as raised_e:
         # This shouldn't happen because cancellation or timeout shouldn't occur...
         # But just in case...
         new_err = HandlerManagerException(
             message=
             "HANDLER ({}): Unable to retrieve exception data from incomplete invocation"
             .format(handler_name),
             cause=raised_e,
         )
         handle_exceptions.handle_background_exception(new_err)
     else:
         if e:
             new_err = HandlerManagerException(
                 message="HANDLER ({}): Error during invocation".format(
                     handler_name),
                 cause=e,
             )
             handle_exceptions.handle_background_exception(new_err)
         else:
             logger.debug(
                 "HANDLER ({}): Successfully completed invocation".
                 format(handler_name))
Example #3
0
    def _start_handler_runner(self, handler_name):
        """Create, and store a task for running a handler"""
        # Run the handler runner on a dedicated event loop for handler runners so as to be
        # isolated from all other client activities
        runner_loop = loop_management.get_client_handler_runner_loop()

        # Client Event handler flow
        if handler_name == CLIENT_EVENT:
            if self._client_event_runner is not None:
                # This branch of code should NOT be reachable due to checks prior to the invocation
                # of this method. The branch exists for safety.
                raise HandlerManagerException(
                    "Cannot create thread for handler runner: {}. Runner thread already exists"
                    .format(handler_name))
            # Client events share a handler
            coro = self._client_event_handler_runner()
            future = asyncio.run_coroutine_threadsafe(coro, runner_loop)
            # Store the future
            self._client_event_runner = future

        # Receiver handler flow
        else:
            if self._receiver_handler_runners[handler_name] is not None:
                # This branch of code should NOT be reachable due to checks prior to the invocation
                # of this method. The branch exists for safety.
                raise HandlerManagerException(
                    "Cannot create task for handler runner: {}. Task already exists"
                    .format(handler_name))
            # Each receiver handler gets its own runner
            inbox = self._get_inbox_for_receive_handler(handler_name)
            coro = self._receiver_handler_runner(inbox, handler_name)
            future = asyncio.run_coroutine_threadsafe(coro, runner_loop)
            # Store the future
            self._receiver_handler_runners[handler_name] = future

        _handler_runner_callback = self._generate_callback_for_handler_runner(
            handler_name)
        future.add_done_callback(_handler_runner_callback)
Example #4
0
    def _start_handler_runner(self, handler_name):
        """Create, and store a task for running a handler
        """
        # First check if the handler runner already exists
        if self._handler_runners[handler_name] is not None:
            # This branch of code should NOT be reachable due to checks prior to the invocation
            # of this method. The branch exists for safety.
            raise HandlerManagerException(
                "Cannot create task for handler runner: {}. Task already exists".format(
                    handler_name
                )
            )

        # Schedule a coroutine with the correct type of handler runner
        inbox = self._get_inbox_for_handler(handler_name)
        if inbox:
            coro = self._inbox_handler_runner(inbox, handler_name)
        else:
            coro = self._event_handler_runner(handler_name)
        future = asyncio.run_coroutine_threadsafe(coro, RUNNER_LOOP)

        # Define a callback for the future (in order to handle any errors)
        def _handler_runner_callback(completed_future):
            try:
                e = completed_future.exception(timeout=0)
            except Exception as raised_e:
                # This shouldn't happen because cancellation or timeout shouldn't occur...
                # But just in case...
                new_err = HandlerManagerException(
                    message="HANDLER RUNNER ({}): Unable to retrieve exception data from incomplete task".format(
                        handler_name
                    ),
                    cause=raised_e,
                )
                handle_exceptions.handle_background_exception(new_err)
            else:
                if e:
                    # If this branch is reached something has gone SERIOUSLY wrong.
                    # We must log the error, and then restart the runner so that the program
                    # does not enter an invalid state
                    new_err = HandlerManagerException(
                        message="HANDLER RUNNER ({}): Unexpected error during task".format(
                            handler_name
                        ),
                        cause=e,
                    )
                    handle_exceptions.handle_background_exception(new_err)
                    # Clear the tracked runner, and start a new one
                    self._handler_runners[handler_name] = None
                    self._start_handler_runner(handler_name)
                else:
                    logger.debug(
                        "HANDLER RUNNER ({}): Task successfully completed without exception".format(
                            handler_name
                        )
                    )

        future.add_done_callback(_handler_runner_callback)

        # Store the future
        self._handler_runners[handler_name] = future
        logger.debug("Future for Handler Runner ({}) was stored".format(handler_name))