Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
*
*/
package org.ak.trafficController.messaging.mem;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.logging.Logger;
/**
* This class can be considered as extension of GenericInMemoryQueue.
* This class is suitable for majority of use cases.
* Using this class means we are saying only one consumer (with multiple instance) is consuming (each for direct and batch).
* {@link GenericInMemoryQueue} can have different type of consumers working on same data which means as queue logic,
* some data will move to one consumer and other data will move to different consumer.
* This use case is very rare, thus this new class tries to hnadle majority of normal use case.
* As we have only one consumer of each type, we can think of adding or decreasing number of consumers easily.
* @author Amit Khosla
*/
public class InMemoryQueue {
static Logger logger = Logger.getLogger(InMemoryQueue.class.getName());
/**
* The actual queue.
*/
GenericInMemoryQueue inMemoryQueue;
/**
* Direct consumer logic.
*/
private Consumer directConsumer;
/**
* Batch consumer logic.
*/
private Consumer> batchConsumer;
/**
* Each time when we need to reset the consumers, the value is reset to ensure we have new consumers registered.
*/
private AtomicInteger directConsumerResetIndex = new AtomicInteger(0);
/**
* Each time when we need to reset the consumers, the value is reset to ensure we have new consumers registered.
*/
private AtomicInteger batchConsumerResetIndex = new AtomicInteger(0);
/**
* Count of direct consumers.
*/
private int directConsumerCount = 1;
/**
* Count of batch consumers.
*/
private int batchConsumerCount = 1;
//Consumers for regisering or unregister a consumer of queue.
private Consumer unregisterDirectConsumer = i->inMemoryQueue.unregister(getDirectConsumerName(i));
private Consumer registerDirectConsumer = i-> inMemoryQueue.register(directConsumer, getDirectConsumerName(i));
private Consumer unregisterBatchConsumer = i->inMemoryQueue.unregister(getBatchConsumerName(i));
private Consumer registerBatchConsumer = i-> inMemoryQueue.registerBatchConsumer(batchConsumer, getBatchConsumerName(i));
/**
* Name of batch consumer.
* @param i Batch number id
* @return Name of batch consumer
*/
protected String getBatchConsumerName(Integer i) {
return "batchConsumer" + i + "_" + batchConsumerResetIndex.get();
}
/**
* Name of direct consumer.
* @param i Direct consumer id
* @return Name of direct consumer
*/
protected String getDirectConsumerName(Integer i) {
return "directConsumer" + i + "_" + directConsumerResetIndex.get();
}
/**
* Creates a new in memory queue.
* @param queueName Name of queue.
*/
public InMemoryQueue(String queueName) {
inMemoryQueue = new GenericInMemoryQueue<>(queueName);
}
/**
* Set batch size of the queue.
* @param batchSize Batch size
* @return InMemoryQueue for ease of use
*/
public InMemoryQueue setBatchSize(int batchSize) {
this.inMemoryQueue.setBatchSize(batchSize);
return this;
}
/**
* Process for add/remove a consumer from given start to given end index.
* @param start Start index from which we have to perform operation
* @param end End index till which we have to perform operation
* @param consumer Consumer which will perform actual operation
*/
protected void processForCounter(int start, int end, Consumer consumer) {
for (int i=start; i<=end;i++) {
consumer.accept(i);
}
}
/**
* Set direct consumer which will work on the data present in queue.
* @param consumer Consumer logic
* @return This object for further modifications
*/
public InMemoryQueue setDirectConsumer(Consumer consumer) {
this.directConsumer =consumer;
if (this.directConsumerCount > 0) {
resetConsumer(unregisterDirectConsumer, registerDirectConsumer, this.directConsumerCount, directConsumerResetIndex);
}
return this;
}
/**
* Whenever a consumer needs to be changed, this method is called to remove current consumers of queue and then add fresh consumers.
* @param unregisterConsumer Unregister consumer logic
* @param registerConsumer Register consumer logic
* @param consumerCount Count of consumers to maintain
* @param index Current index
*/
protected void resetConsumer(Consumer unregisterConsumer, Consumer registerConsumer, int consumerCount, AtomicInteger index) {
processForCounter(0, consumerCount, unregisterConsumer);
index.incrementAndGet();
processForCounter(1, consumerCount,registerConsumer);
}
/**
* Set batch consumer logic
* @param batchConsumer Batch consumer
* @return This object for further modification
*/
public InMemoryQueue setBatchConsumer(Consumer> batchConsumer) {
this.batchConsumer = batchConsumer;
if (this.batchConsumerCount > 0) {
resetConsumer(unregisterBatchConsumer, registerBatchConsumer, this.batchConsumerCount, this.batchConsumerResetIndex);
}
return this;
}
/**
* This method is responsible for increasing/decreasing consumer count.
* @param currentCount Current count
* @param newCount New count which needs to be set
* @param registerCounsumer Register logic
* @param unregisterConsumer Unregister logic
*/
protected void setConsumerCount(int currentCount, int newCount, Consumer registerCounsumer, Consumer unregisterConsumer) {
if (currentCountnewCount) {
processForCounter(newCount+1, currentCount, unregisterConsumer);
}
}
/**
* Set direct consumer count.
* @param directConsumerCount Direct consumer count
* @return This object for further modification
*/
public InMemoryQueue setDirectConsumerCount(int directConsumerCount) {
setConsumerCount(this.directConsumerCount, directConsumerCount, registerDirectConsumer, unregisterDirectConsumer);
this.directConsumerCount = directConsumerCount;
return this;
}
/**
* Reset batch consumer count.
* @param batchConsumerCount batch consumers count
* @return Same instance on which we are looking for setting consumers
*/
public InMemoryQueue setBatchConsumerCount(int batchConsumerCount) {
setConsumerCount(this.batchConsumerCount, batchConsumerCount, registerBatchConsumer, unregisterBatchConsumer);
this.batchConsumerCount = batchConsumerCount;
return this;
}
/**
* Shutdown the queue.
* All consumers are shutdown. Should be called before last use of queue.
*/
public void shutdown() {
this.inMemoryQueue.shutdown();
}
/**
* This method adds data present in input collection
* @param input Collection containing data
*/
public void addAllFromCollection(Collection input) {
this.inMemoryQueue.add(input);
}
/**
* Add item to the queue.
* @param i Item to be added to queue
*/
public void add(T i) {
this.inMemoryQueue.add(i);
}
/**
* Get current batch consumer count
* @return Batch consumer count
*/
public Integer getBatchConsumerCount() {
return this.batchConsumerCount;
}
/**
* Get direct consumer count.
* @return Direct consumer count
*/
public Integer getDirectConsumerCount() {
return this.directConsumerCount;
}
/**
* Get current number of items in queue.
* @return items in queue
*/
public Long getNumberOfItemsInQueue() {
return this.inMemoryQueue.getNumberOfItemsInQueue();
}
/**
* Increment direct consumer count.
*/
public void incrementDirectConsumer() {
this.directConsumerCount++;
this.inMemoryQueue.register(this.directConsumer, getDirectConsumerName(this.directConsumerCount));
}
/**
* Decrement direct consumer count.
*/
public void decrementDirectConsumer() {
this.inMemoryQueue.unregister(getDirectConsumerName(this.directConsumerCount));
this.directConsumerCount--;
}
/**
* Increment batch consumer count.
*/
public void incrementBatchConsumer() {
this.batchConsumerCount++;
this.inMemoryQueue.registerBatchConsumer(this.batchConsumer, getBatchConsumerName(this.batchConsumerCount));
}
/**
* Decrement batch consumer count.
*/
public void decrementBatchConsumer() {
this.inMemoryQueue.unregister(getBatchConsumerName(this.batchConsumerCount));
this.batchConsumerCount--;
}
/**
* This method lets us know that for this queue, any direct consumer set.
* @return true if already some direct consumer set
*/
public boolean isDirectConsumerSet() {
return this.directConsumer != null;
}
/**
* This method lets us know that for this queue, any batch consumer set.
* @return true if already some batch consumer set
*/
public boolean isBatchConsumerSet() {
return this.batchConsumer != null;
}
/**
* This method clears the queue. All data present in queue is removed.
* The data present in queue is first consumed by passed consumers.
* @param consumer Consumers consuming data present in queue
*/
protected void clear(Consumer>... consumer) {
this.inMemoryQueue.clear(consumer);
}
/**
* Remove direct consumer.
*/
public void removeDirectConsumer() {
this.directConsumer = null;
inMemoryQueue.removeAllDirectConsumers();
}
/**
* Remove Batch Consumer.
*/
public void removeBatchConsumer() {
this.batchConsumer = null;
inMemoryQueue.removeAllBatchConsumers();
}
}