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 _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
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
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
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
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 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))
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))
def ctx(): if not has_ctx(): raise exc.ApplicationContextNotFoundException() return utils.get_thread_local(_CTX_THREAD_LOCAL_NAME)
def _get_thread_local_session(): return utils.get_thread_local(_DB_SESSION_THREAD_LOCAL_NAME)
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