sea
sea

Reputation: 113

SpringAMQP delay

I'm having trouble to identify a way to delay message level in SpringAMQP. I call a Webservice if the service is not available or if it throws some exception I store all the requests into RabbitMQ queue and i keep retry the service call until it executes successfully. If the service keeps throwing an error or its not available the rabbitMQ listener keeps looping.( Meaning Listener retrieves the message and make service call if any error it re-queue the message)

I restricted the looping until X hours using MessagePostProcessor however i wanted to enable delay on message level and every time it tries to access the service. For example 1st try 3000ms delay and second time 6000ms so on until i try x number of time.

It would be great if you provide a few examples.

Could you please provide me some idea on this?

Upvotes: 1

Views: 535

Answers (2)

sea
sea

Reputation: 113

I added CustomeMessage delay exchange

    @Bean
    CustomExchange delayExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange("delayed-exchange", "x-delayed-message", true, false, args);
    }

Added MessagePostProcessor

  if (message.getMessageProperties().getHeaders().get("x-delay") == null) {
            message.getMessageProperties().setHeader("x-delay", 10000);
        } else {

            Integer integer = (Integer) message.getMessageProperties().getHeaders().get("x-delay");
            if (integer < 60000) {
                integer = integer + 10000;
                message.getMessageProperties().setHeader("x-delay", integer);
            }
        }

First time it delays 30 seconds and adds 10seconds each time till it reaches 600 seconds.This should be configurable.

And finally send the message to 

    rabbitTemplate.convertAndSend("delayed-exchange", queueName,message, rabbitMQMessagePostProcessor);

Upvotes: 1

Artem Bilan
Artem Bilan

Reputation: 121272

Well, it isn't possible the way you do that.

Message re-queuing is fully similar to transaction rallback, where the system returns to the state before an exception. So, definitely you can't modify a message to return to the queue.

Probably you have to take a look into Spring Retry project for the same reason and poll message from the queue only once and retries in memory until successful answer or retry policy exhausting. In the end you can just drop message from the queue or move it into DLQ.

See more info in the Reference Manual.

Upvotes: 1

Related Questions