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

com.rabbitmq.client.impl.ConsumerDispatcher Maven / Gradle / Ivy

Go to download

The RabbitMQ Java client library allows Java applications to interface with RabbitMQ.

There is a newer version: 5.22.0
Show newest version
// Copyright (c) 2007-2023 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
//
// This software, the RabbitMQ Java client library, is triple-licensed under the
// Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2.  For the ASL,
// please see LICENSE-APACHE2.
//
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
// either express or implied. See the LICENSE file for specific language governing
// rights and limitations of this software.
//
// If you have any questions regarding licensing, please contact us at
// [email protected].

package com.rabbitmq.client.impl;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException;
import com.rabbitmq.utility.Utility;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * Dispatches notifications to a {@link Consumer} on an internally-managed executor service and work
 * pool.
 * 

* Each {@link Channel} has a single ConsumerDispatcher, but the executor service and work * pool may be shared with other channels, typically those on the same {@link AMQConnection}. */ final class ConsumerDispatcher { private final ConsumerWorkService workService; private final AMQConnection connection; private final Channel channel; private volatile boolean shuttingDown = false; private volatile boolean shutdownConsumersDriven = false; private volatile CountDownLatch shutdownConsumersComplete; private volatile ShutdownSignalException shutdownSignal = null; public ConsumerDispatcher(AMQConnection connection, Channel channel, ConsumerWorkService workService) { this.connection = connection; this.channel = channel; workService.registerKey(channel); this.workService = workService; } /** Prepare for shutdown of all consumers on this channel */ public void quiesce() { // Prevent any more items being put on the queue (except the shutdown item) this.shuttingDown = true; } public void setUnlimited(boolean unlimited) { this.workService.setUnlimited(channel, unlimited); } public void handleConsumeOk(final Consumer delegate, final String consumerTag) { executeUnlessShuttingDown( new Runnable() { @Override public void run() { try { delegate.handleConsumeOk(consumerTag); } catch (Throwable ex) { connection.getExceptionHandler().handleConsumerException( channel, ex, delegate, consumerTag, "handleConsumeOk"); } } }); } public void handleCancelOk(final Consumer delegate, final String consumerTag) { executeUnlessShuttingDown( new Runnable() { @Override public void run() { try { delegate.handleCancelOk(consumerTag); } catch (Throwable ex) { connection.getExceptionHandler().handleConsumerException( channel, ex, delegate, consumerTag, "handleCancelOk"); } } }); } public void handleCancel(final Consumer delegate, final String consumerTag) { executeUnlessShuttingDown( new Runnable() { @Override public void run() { try { delegate.handleCancel(consumerTag); } catch (Throwable ex) { connection.getExceptionHandler().handleConsumerException( channel, ex, delegate, consumerTag, "handleCancel"); } } }); } public void handleRecoverOk(final Consumer delegate, final String consumerTag) { executeUnlessShuttingDown( new Runnable() { @Override public void run() { delegate.handleRecoverOk(consumerTag); } }); } public void handleDelivery(final Consumer delegate, final String consumerTag, final Envelope envelope, final AMQP.BasicProperties properties, final byte[] body) throws IOException { executeUnlessShuttingDown( new Runnable() { @Override public void run() { try { delegate.handleDelivery(consumerTag, envelope, properties, body); } catch (Throwable ex) { connection.getExceptionHandler().handleConsumerException( channel, ex, delegate, consumerTag, "handleDelivery"); } } }); } public CountDownLatch handleShutdownSignal(final Map consumers, final ShutdownSignalException signal) { // ONLY CASE WHERE WE IGNORE shuttingDown if (!this.shutdownConsumersDriven) { final CountDownLatch latch = new CountDownLatch(1); this.shutdownConsumersComplete = latch; this.shutdownConsumersDriven = true; // Execute shutdown processing even if there are no consumers. execute(new Runnable() { @Override public void run() { ConsumerDispatcher.this.notifyConsumersOfShutdown(consumers, signal); ConsumerDispatcher.this.shutdown(signal); ConsumerDispatcher.this.workService.stopWork(ConsumerDispatcher.this.channel); latch.countDown(); } }); } return this.shutdownConsumersComplete; } private void notifyConsumersOfShutdown(Map consumers, ShutdownSignalException signal) { for (Map.Entry consumerEntry : consumers.entrySet()) { notifyConsumerOfShutdown(consumerEntry.getKey(), consumerEntry.getValue(), signal); } } private void notifyConsumerOfShutdown(String consumerTag, Consumer consumer, ShutdownSignalException signal) { try { consumer.handleShutdownSignal(consumerTag, signal); } catch (Throwable ex) { connection.getExceptionHandler().handleConsumerException( channel, ex, consumer, consumerTag, "handleShutdownSignal"); } } private void executeUnlessShuttingDown(Runnable r) { if (!this.shuttingDown) execute(r); } private void execute(Runnable r) { checkShutdown(); this.workService.addWork(this.channel, r); } private void shutdown(ShutdownSignalException signal) { this.shutdownSignal = signal; } private void checkShutdown() { if (this.shutdownSignal != null) { throw Utility.fixStackTrace(this.shutdownSignal); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy