Ejemplo n.º 1
0
    def _on_response(response, message):
        """Callback on response.

        This method is automatically called when a response is incoming and
        decides if it is the message we are waiting for - the message with the
        result.

        :param response: the body of the amqp message already deserialized
            by kombu
        :param message: the plain amqp kombu.message with additional
            information
        """
        LOG.debug("Got response: {0}".format(response))

        try:
            message.ack()
        except Exception as e:
            LOG.exception("Failed to acknowledge AMQP message: %s" % e)
        else:
            LOG.debug("AMQP message acknowledged.")

            # Process response.
            if (utils.get_thread_local(CORR_ID) ==
                    message.properties['correlation_id']):
                utils.set_thread_local(IS_RECEIVED, True)

                # TODO(ddeja): Decide if raising exception to kombu is best
                # behaviour.
                if message.properties.get('type') == 'error':
                    raise response
                utils.set_thread_local(RESULT, response)
Ejemplo n.º 2
0
    def _on_response(response, message):
        """Callback on response.

        This method is automatically called when a response is incoming and
        decides if it is the message we are waiting for - the message with the
        result.

        :param response: the body of the amqp message already deserialized
            by kombu
        :param message: the plain amqp kombu.message with additional
            information
        """
        LOG.debug("Got response: {0}".format(response))

        try:
            message.ack()
        except Exception as e:
            LOG.exception("Failed to acknowledge AMQP message: %s" % e)
        else:
            LOG.debug("AMQP message acknowledged.")

            # Process response.
            if (utils.get_thread_local(CORR_ID) ==
                    message.properties['correlation_id']):
                utils.set_thread_local(IS_RECEIVED, True)

                # TODO(ddeja): Decide if raising exception to kombu is best
                # behaviour.
                if message.properties.get('type') == 'error':
                    raise response
                utils.set_thread_local(RESULT, response)
Ejemplo n.º 3
0
def _get_queue():
    queue = utils.get_thread_local(_THREAD_LOCAL_NAME)

    if queue is None:
        raise RuntimeError(
            'Action queue is not initialized for the current thread.'
            ' Most likely some transactional method is not decorated'
            ' with action_queue.process()')

    return queue
Ejemplo n.º 4
0
def _get_queues():
    queues = utils.get_thread_local(_THREAD_LOCAL_NAME)

    if queues is None:
        raise RuntimeError(
            'Operation queue is not initialized for the current thread.'
            ' Most likely some engine method is not decorated with'
            ' operation_queue.run()')

    return queues
Ejemplo n.º 5
0
def _get_queue():
    queue = utils.get_thread_local(_THREAD_LOCAL_NAME)

    if queue is None:
        raise RuntimeError(
            'Action queue is not initialized for the current thread.'
            ' Most likely some transactional method is not decorated'
            ' with action_queue.process()'
        )

    return queue
Ejemplo n.º 6
0
def _get_queues():
    queues = utils.get_thread_local(_THREAD_LOCAL_NAME)

    if queues is None:
        raise RuntimeError(
            'Operation queue is not initialized for the current thread.'
            ' Most likely some engine method is not decorated with'
            ' operation_queue.run()'
        )

    return queues
Ejemplo n.º 7
0
    def _wait_for_result(self):
        """Waits for the result from the server.

        Waits for the result from the server, checks every second if
        a timeout occurred. If a timeout occurred - the `RpcTimeout` exception
        will be raised.
        """
        while not utils.get_thread_local(IS_RECEIVED):
            try:
                self.conn.drain_events(timeout=self._timeout)
            except socket.timeout:
                raise exc.MistralException("RPC Request timeout")
Ejemplo n.º 8
0
    def _wait_for_result(self):
        """Waits for the result from the server.

        Waits for the result from the server, checks every second if
        a timeout occurred. If a timeout occurred - the `RpcTimeout` exception
        will be raised.
        """
        while not utils.get_thread_local(IS_RECEIVED):
            try:
                self.conn.drain_events(timeout=self._timeout)
            except socket.timeout:
                raise exc.MistralException("RPC Request timeout")
Ejemplo n.º 9
0
def log_to_file(info, context=None):
    attrs = [
        str(info['timestamp']),
        info['base_id'],
        info['parent_id'],
        info['trace_id'],
        info['name']
    ]

    th_local_name = '_profiler_trace_%s_start_time_' % info['trace_id']

    if info['name'].endswith('-start'):
        utils.set_thread_local(
            th_local_name,
            datetime.datetime.utcnow()
        )

        # Insert a blank sequence for a trace start.
        attrs.insert(1, ' ' * 8)

    if info['name'].endswith('-stop'):
        delta = (
            datetime.datetime.utcnow() - utils.get_thread_local(th_local_name)
        ).total_seconds()

        utils.set_thread_local(th_local_name, None)

        # Insert a blank sequence for a trace start.
        attrs.insert(1, str(delta))

        if delta > 0.5:
            attrs.append(' <- !!!')

    if 'info' in info and 'db' in info['info']:
        db_info = copy.deepcopy(info['info']['db'])

        db_info['params'] = {
            k: str(v) if isinstance(v, datetime.datetime) else v
            for k, v in db_info.get('params', {}).items()
        }

        attrs.append(json.dumps(db_info))

    PROFILER_LOG.info(' '.join(attrs))
Ejemplo n.º 10
0
def log_to_file(info, context=None):
    attrs = [
        str(info['timestamp']), info['base_id'], info['parent_id'],
        info['trace_id'], info['name']
    ]

    th_local_name = '_profiler_trace_%s_start_time_' % info['trace_id']

    if info['name'].endswith('-start'):
        utils.set_thread_local(th_local_name, datetime.datetime.utcnow())

        # Insert a blank sequence for a trace start.
        attrs.insert(1, ' ' * 8)

    if info['name'].endswith('-stop'):
        delta = (datetime.datetime.utcnow() -
                 utils.get_thread_local(th_local_name)).total_seconds()

        utils.set_thread_local(th_local_name, None)

        # Insert a blank sequence for a trace start.
        attrs.insert(1, str(delta))

        if delta > 0.5:
            attrs.append(' <- !!!')

    if 'info' in info and 'db' in info['info']:
        db_info = copy.deepcopy(info['info']['db'])

        db_info['params'] = {
            k: str(v) if isinstance(v, datetime.datetime) else v
            for k, v in db_info.get('params', {}).items()
        }

        attrs.append(json.dumps(db_info))

    PROFILER_LOG.info(' '.join(attrs))
Ejemplo n.º 11
0
def ctx():
    if not has_ctx():
        raise exc.ApplicationContextNotFoundException()

    return utils.get_thread_local(_CTX_THREAD_LOCAL_NAME)
Ejemplo n.º 12
0
def _get_thread_local_session():
    return utils.get_thread_local(_DB_SESSION_THREAD_LOCAL_NAME)
Ejemplo n.º 13
0
def ctx():
    if not has_ctx():
        raise exc.ApplicationContextNotFoundException()

    return utils.get_thread_local(_CTX_THREAD_LOCAL_NAME)
Ejemplo n.º 14
0
def _get_thread_local_session():
    return utils.get_thread_local(_DB_SESSION_THREAD_LOCAL_NAME)
Ejemplo n.º 15
0
class KombuRPCClient(rpc_base.RPCClient, kombu_base.Base):
    def __init__(self, conf):
        super(KombuRPCClient, self).__init__(conf)

        self.exchange = conf.get('exchange', '')
        self.user_id = conf.get('user_id', 'guest')
        self.password = conf.get('password', 'guest')
        self.topic = conf.get('topic', 'mistral')
        self.server_id = conf.get('server_id', '')
        self.host = conf.get('host', 'localhost')
        self.port = conf.get('port', 5672)
        self.virtual_host = conf.get('virtual_host', '/')
        self.durable_queue = conf.get('durable_queues', False)
        self.auto_delete = conf.get('auto_delete', False)
        self._timeout = conf.get('timeout', 60)
        self.conn = self._make_connection(self.host, self.port, self.user_id,
                                          self.password, self.virtual_host)

        # Create exchange.
        exchange = self._make_exchange(self.exchange,
                                       durable=self.durable_queue,
                                       auto_delete=self.auto_delete)

        # Create queue.
        queue_name = utils.generate_unicode_uuid()
        self.callback_queue = kombu.Queue(queue_name,
                                          exchange=exchange,
                                          routing_key=queue_name,
                                          durable=False,
                                          exclusive=True,
                                          auto_delete=True)

        # Create consumer.
        self.consumer = kombu.Consumer(channel=self.conn.channel(),
                                       queues=self.callback_queue,
                                       callbacks=[self._on_response],
                                       accept=['pickle', 'json'])
        self.consumer.qos(prefetch_count=1)

    @staticmethod
    def _on_response(response, message):
        """Callback on response.

        This method is automatically called when a response is incoming and
        decides if it is the message we are waiting for - the message with the
        result.

        :param response: the body of the amqp message already deserialized
            by kombu
        :param message: the plain amqp kombu.message with additional
            information
        """
        LOG.debug("Got response: {0}".format(response))

        try:
            message.ack()
        except Exception as e:
            LOG.exception("Failed to acknowledge AMQP message: %s" % e)
        else:
            LOG.debug("AMQP message acknowledged.")

            # Process response.
            if (utils.get_thread_local(CORR_ID) ==
                    message.properties['correlation_id']):
                utils.set_thread_local(IS_RECEIVED, True)

                # TODO(ddeja): Decide if raising exception to kombu is best
                # behaviour.
                if message.properties.get('type') == 'error':
                    raise response
                utils.set_thread_local(RESULT, response)

    def _wait_for_result(self):
        """Waits for the result from the server.

        Waits for the result from the server, checks every second if
        a timeout occurred. If a timeout occurred - the `RpcTimeout` exception
        will be raised.
        """
        while not utils.get_thread_local(IS_RECEIVED):
            try:
                self.conn.drain_events(timeout=self._timeout)
            except socket.timeout:
                raise exc.MistralException("RPC Request timeout")

    def _call(self, ctx, method, target, async=False, **kwargs):
        """Performs a remote call for the given method.

        :param ctx: authentication context associated with mistral
        :param method: name of the method that should be executed
        :param kwargs: keyword parameters for the remote-method
        :param target: Server name
        :param async: bool value means whether the request is
            asynchronous or not.
        :return: result of the method or None if async.
        """
        utils.set_thread_local(CORR_ID, utils.generate_unicode_uuid())
        utils.set_thread_local(IS_RECEIVED, False)

        self.consumer.consume()

        body = {
            'rpc_ctx': ctx.to_dict(),
            'rpc_method': method,
            'arguments': kwargs,
            'async': async
        }

        LOG.debug("Publish request: {0}".format(body))

        # Publish request.
        with kombu.producers[self.conn].acquire(block=True) as producer:
            producer.publish(body=body,
                             exchange=self.exchange,
                             routing_key=self.topic,
                             reply_to=self.callback_queue.name,
                             correlation_id=utils.get_thread_local(CORR_ID),
                             delivery_mode=2)

        # Start waiting for response.
        if async:
            return

        self._wait_for_result()
        result = utils.get_thread_local(RESULT)

        self._clear_thread_local()

        return result