All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rabbitmq.jms.client.PublisherConfirmsUtils Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2019-2020 VMware, Inc. or its affiliates. All rights reserved.
package com.rabbitmq.jms.client;

import com.rabbitmq.client.Channel;

import javax.jms.Message;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;

/**
 * Utility class to handle publisher confirms.
 *
 * @since 1.13.0
 */
class PublisherConfirmsUtils {

    /**
     * Enables publisher confirms support.
     * 

* Adds a {@link com.rabbitmq.client.ConfirmListener} to the AMQP {@link Channel} * and notifies the user-provided {@link ConfirmListener} when confirms notified * arrive. *

* Returns a {@link PublishingListener} that must be called whenever a message is published. * * @param channel * @param confirmListener * @return */ static PublishingListener configurePublisherConfirmsSupport(Channel channel, ConfirmListener confirmListener) { final Map outstandingConfirms = new ConcurrentHashMap<>(); final AtomicLong multipleLowerBound = new AtomicLong(1); PublishingListener publishingListener = (message, sequenceNumber) -> { outstandingConfirms.put(sequenceNumber, message); }; channel.addConfirmListener(new com.rabbitmq.client.ConfirmListener() { @Override public void handleAck(long deliveryTag, boolean multiple) { cleanPublisherConfirmsCorrelation( outstandingConfirms, multipleLowerBound, deliveryTag, multiple, message -> confirmListener.handle(new PublisherConfirmContext(message, true)) ); } @Override public void handleNack(long deliveryTag, boolean multiple) { cleanPublisherConfirmsCorrelation( outstandingConfirms, multipleLowerBound, deliveryTag, multiple, message -> confirmListener.handle(new PublisherConfirmContext(message, false)) ); } }); return publishingListener; } /** * Cleans the data structure used to correlate publishing sequence numbers to messages when a confirm comes in. *

* Invoke a provided callback for each message confirmed/nack-ed. * * @param outstandingConfirms * @param multipleLowerBound * @param deliveryTag * @param multiple * @param messageConsumer */ private static void cleanPublisherConfirmsCorrelation(Map outstandingConfirms, AtomicLong multipleLowerBound, long deliveryTag, boolean multiple, Consumer messageConsumer) { Long lowerBound = multipleLowerBound.get(); if (multiple) { for (long i = lowerBound; i <= deliveryTag; i++) { Message message = outstandingConfirms.remove(i); if (message != null) { messageConsumer.accept(message); } } } else { Message message = outstandingConfirms.remove(deliveryTag); if (message != null) { messageConsumer.accept(message); } if (deliveryTag == lowerBound + 1) { multipleLowerBound.compareAndSet(lowerBound, deliveryTag); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy