async def on_message(self, message: IncomingMessage): if message.headers['target'] == self.name and self.ifPropertyAllowed( message.headers['property']) and self.runChecks( message.headers): self.exec(message.headers, message) else: message.nack()
async def _on_fail(self, message: IncomingMessage, error: Exception): try: if message.reply_to: response = self.serializer.serialize( Response( status=getattr(error, 'status', 500), body=ErrorResponseBody(error=str(error)).dict() ) ) await self.channel.default_exchange.publish( Message( response, delivery_mode=message.delivery_mode, correlation_id=message.correlation_id, timestamp=int(time.time()), ), message.reply_to, mandatory=False ) finally: logger.exception( 'Invalid message (%s) with routing_key %s, ' "don't retry it! Correlation id: %s", message.body, message.routing_key, message.headers.get(Headers.correlation_id) if message.headers else None, ) message.nack(requeue=False)
async def _process_message(self, message: IncomingMessage, registered_obj: RegisteredCoroOrGen, **callable_kwargs): logger.debug(f"Processing message {message.delivery_tag}") try: if inspect.iscoroutinefunction(registered_obj.coro_or_gen): # it returns return_val = await registered_obj.coro_or_gen(**callable_kwargs ) if return_val is not None: await self._handle_return_value(message, return_val) else: # it yields async for v in registered_obj.coro_or_gen(**callable_kwargs): if v is not None: await self._handle_return_value(message, v) # At this point, we're processed the message and sent along new ones successfully. We can ack the original message # TODO consider doing all of this transactionally logger.debug(f"Acking message {message.delivery_tag}") message.ack() except asyncio.CancelledError: # We were told to cancel. nack with requeue so someone else will pick up the work message.nack(requeue=True) logger.info("Cancellation requested.") raise except Exception as e_: await self._handle_message_exception(message, e_)
async def _on_message(self, message: aio_pika.IncomingMessage): logging.debug(f'Received message {str(message.body)}.') if getattr(self, 'custom_consume_function', None): if not await self.custom_consume_function(**self.custom_consume_function_kwargs): self.logger.error('Failed process message.') message.nack() return self.logger.info('Message has been successfully processed.') message.ack()
def __call__(self, message: IncomingMessage): value = int(message.body.decode()) if value == 3 and self.rejected < 3: print('[blue]Nacking[/blue] 3') message.nack() self.rejected += 1 elif value == 5: print('[red]Rejecting[/red] 5') message.reject() else: print(f'[green]Processed[/green] {value}') message.ack()
async def _on_fail(self, message: IncomingMessage, error: Exception): try: if message.reply_to: response = self.serializer.serialize( Response( status=getattr(error, 'status', 500), body=ErrorResponseBody(error=str(error)).dict() ) ) await self.channel.default_exchange.publish( Message( response, delivery_mode=message.delivery_mode, correlation_id=message.correlation_id, timestamp=int(time.time()), ), message.reply_to, mandatory=False ) finally: message.nack(requeue=False)
async def _handle_msg( self, action: BindConsumer, pika_msg: PikaIncomingMessage, msg: AmqpMsg, ): self.log.info('received msg {} in queue {} ' 'from exchange {} topic {}'.format( pika_msg.delivery_tag, action.queue, msg.exchange, msg.topic, )) self.log.debug('msg received: {}'.format(str(msg))) result = True try: result = await action.callback(msg) self.log.debug('msg processed') except Exception as e: self.log.error('an error occurred when processing message') result = False if self._consumer_error_handlers: for handler in self._consumer_error_handlers: handler(e) else: traceback.print_exc() if not action.auto_ack and result: self.log.debug('sending ack for message {}'.format( pika_msg.delivery_tag)) pika_msg.ack() elif not action.auto_ack: self.log.debug('sending nack for message {}'.format( pika_msg.delivery_tag)) pika_msg.nack(requeue=action.nack_requeue)
async def _handle_exception(self, message: IncomingMessage, error: Exception): if not isinstance(error, RecoverableErrorBase): await self._on_fail(message, error) else: logger.exception( 'Cannot process message "%s" in "%s"!. Because of %s.', message.delivery_tag, message.routing_key, error ) headers: typing.Dict = message.headers or {} attempts_max: typing.AnyStr = smart_int(headers.get(Headers.retry_attempts_max)) attempts_nr: typing.AnyStr = smart_int(headers.get(Headers.retry_attempt_nr), 1) if attempts_max and attempts_max > attempts_nr: headers[Headers.retry_attempt_nr] = str(attempts_nr + 1) backoff: int = int(math.pow(2, min(attempts_nr - 1, 7))) new_message: Message = Message(message.body, type=message.type, reply_to=message.reply_to, delivery_mode=message.delivery_mode, message_id=message.message_id, correlation_id=message.correlation_id, expiration=backoff, headers=headers) expires_at = headers.get(Headers.expired_at) if expires_at and int(expires_at) <= (time.time() + backoff): logger.exception( 'timeout %s. Message will be expired %s, ' "don't retry it! Correlation id: %s", message.routing_key, expires_at, headers.get(Headers.correlation_id), ) await self._on_fail(message, error) else: try: logger.exception( 'Routing key: %s. Retry attempt %s after %s seconds...', message.routing_key, attempts_nr, backoff ) await self.dlx_exchange.publish( new_message, routing_key=message.routing_key, mandatory=False ) except Exception: # noqa logger.exception('Error on publish retry message for %s', message.routing_key) await self._on_fail(message, error) else: logger.exception( 'max retries (%s) reached %s, ' "don't retry it! Correlation id: %s", attempts_max, message.routing_key, headers.get(Headers.correlation_id), ) message.nack(requeue=False)