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

org.ak.trafficController.messaging.mem.MultiplexInMemoryQueueManager Maven / Gradle / Ivy

package org.ak.trafficController.messaging.mem;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

import org.ak.trafficController.messaging.mem.wrapper.MuxWrapper;
import org.apache.commons.collections.CollectionUtils;

/**
 * This class is for having single set of consumers for all in memory queue.
 * There can be a requirement where we want only one queue to be used and having all settings done for this queue.
 * The consumers will be registered and based on the object, data will be picked.
 * @author Amit Khosla
 */
public class MultiplexInMemoryQueueManager {

	/**
	 * Different consumers which will be used for given type of data.
	 */
	private Map> consumersMap = new ConcurrentHashMap<>();
	
	/**
	 * Actual queue which will be used.
	 */
	private InMemoryQueue muxQueue = new InMemoryQueue<>("muxQueue");
	
	/**
	 * Data having missed key. Might be at start we do not have consumer added for it.
	 */
	private Map> missedMuxs = new ConcurrentHashMap<>();
	
	/**
	 * Tuner which will be used.
	 */
	private InMemoryQueueTuner tuner = new InMemoryQueueTuner();
	
	/**
	 * Constructor
	 */
	public MultiplexInMemoryQueueManager() {
		init();
	}

	protected void init() {
		Consumer consumer = mux-> {
			Consumer wrappedConsumer = consumersMap.get(mux.getKey());
			if (wrappedConsumer != null) {
				wrappedConsumer.accept(mux);
			} else {
				putInMissedMap(mux);
			}
		};
		muxQueue.setDirectConsumer(consumer);
	}
	
	/**
	 * Put in missed map for any key for which consumer is not set yet.
	 * @param mux Mux which will be put in the missed items
	 */
	private void putInMissedMap(MuxWrapper mux) {
		String key = mux.getKey();
		List list = missedMuxs.get(key);
		if (list == null) {
			synchronized (missedMuxs) {
				if (list == null) {
					list = new ArrayList<>();
					missedMuxs.put(key, list);
				}
			}
		}
		list.add(mux);
	}

	/**
	 * Register a consumer against a key. All data having this key will be processed using this consmer.
	 * @param key Key of data
	 * @param consumer Consumer logic
	 * @param  type of consumer
	 */
	public  void register(String key, Consumer consumer) {
		consumersMap.put(key, getConsumer(consumer));
		/// TODO - Should not we call the consumer directly here?
		enqueMissedMuxIfAny(key);
	}

	/**
	 * Enqueue all the missed items back to the queue.
	 * @param key Key for which any missing items is processed
	 */
	protected void enqueMissedMuxIfAny(String key) {
		List list = missedMuxs.get(key);
		if (!CollectionUtils.isEmpty(list)) {
			muxQueue.addAllFromCollection(list);
		}
	}

	/**
	 * Get the consumer of queue which will process the actual paased consumer.
	 * @param consumer Actual consumer logic
	 * @return Consumer of queue
	 * @param  type of consumer
	 */
	protected  Consumer getConsumer(Consumer consumer) {
		return muxWrapper->consumer.accept((T) muxWrapper.getObj());
	}
	
	/**
	 * Set dynamic nature for this queue.
	 * @return Dynamic settings to further tune it
	 */
	public DynamicSettings setDynamicSettings() {
		DynamicSettings dynamicSettings = new DynamicSettings().setQueue(muxQueue);
		tuner.dynamicSettings.add(dynamicSettings);
		tuner.startTuning();
		return dynamicSettings;
	}

	/**
	 * Add item in the queue for given key.
	 * @param key Key for which this data is designated
	 * @param item Item to be added
	 * @param  type of data
	 */
	public  void add(String key, T item) {
		muxQueue.add(new MuxWrapper().setObj(item).setKey(key));
	}

	/**
	 * Add multiple items in the queue for given queue.
	 * All items passed in collection will be added to the queue.
	 * @param key Key against which we want to add the data
	 * @param list Collection having data
	 * @param  type of data
	 */
	public  void addMultiple(String key, List list) {
		list.forEach(item->muxQueue.add(new MuxWrapper().setKey(key).setObj(item)));
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy