com.rabbitmq.jms.client.DelayedReceiver Maven / Gradle / Ivy
/* Copyright (c) 2013 Pivotal Software, Inc. All rights reserved. */
package com.rabbitmq.jms.client;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.rabbitmq.client.GetResponse;
import com.rabbitmq.jms.util.TimeTracker;
/**
* Receive messages from RMQ Queue with delay (timer).
*
* The blocking method get()
only returns with null
when either the Receiver is closed,
* or the timeout expires.
*
*/
class DelayedReceiver {
private final Logger logger = LoggerFactory.getLogger(DelayedReceiver.class);
private static final TimeTracker POLLING_INTERVAL = new TimeTracker(100, TimeUnit.MILLISECONDS); // one tenth of a second
@SuppressWarnings("unused")
private final int batchingSize;
private final RMQMessageConsumer rmqMessageConsumer;
private final Object responseLock = new Object();
private boolean aborted = false; // @GuardedBy(responseLock)
/**
* @param batchingSize - the intended limit of messages that can be pre-fetched.
* @param rmqMessageConsumer - the JMS MessageConsumer we are serving.
*/
public DelayedReceiver(int batchingSize, RMQMessageConsumer rmqMessageConsumer) {
this.batchingSize = batchingSize;
this.rmqMessageConsumer = rmqMessageConsumer;
}
/**
* Get a message; if there isn't one, try again at intervals not exceeding the total time available. Aborts if closed while polling.
* @param tt - keeps track of the time available
* @return message gotten, or null
if timeout or connection closed.
*/
public GetResponse get(TimeTracker tt) {
try {
synchronized (this.responseLock) {
GetResponse resp = this.rmqMessageConsumer.getFromRabbitQueue();
if (resp != null) return resp;
while (!this.aborted && !tt.timedOut()) {
resp = this.rmqMessageConsumer.getFromRabbitQueue();
if (resp != null)
break;
new TimeTracker(POLLING_INTERVAL).timedWait(this.responseLock);
}
return resp;
}
} catch (InterruptedException e) {
logger.warn("Get interrupted while buffer.poll-ing.", e);
Thread.currentThread().interrupt();
return null;
}
}
private void abort() {
synchronized(this.responseLock) {
this.aborted = true;
this.responseLock.notifyAll();
}
}
public void close() {
this.abort();
}
}