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

org.zbus.remoting.nio.DispatcherManager Maven / Gradle / Ivy

package org.zbus.remoting.nio;

import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

 

public abstract class DispatcherManager implements Closeable {
	private static final Logger log = LoggerFactory.getLogger(DispatcherManager.class);
	private final Codec codec; 
	
	private ExecutorService executor;
	
	private final int dispatcherCount;
	private final Dispatcher[] dispatchers;
	private AtomicInteger dispactherIndex = new AtomicInteger(0);
	private final String dispatcherNamePrefix;
	
	protected volatile boolean started = false;  
	
	public DispatcherManager(
			Codec codec,  
			ExecutorService executor, 
			int dispatcherCount, 
			String dispatcherNamePrefix) throws IOException{
		
		this.dispatcherCount = dispatcherCount; 
		this.codec = codec; 
		this.executor = executor;
		this.dispatcherNamePrefix = dispatcherNamePrefix;
		
		this.dispatchers = new Dispatcher[this.dispatcherCount];
		
		for(int i=0;i=this.dispatcherCount){
			throw new IllegalArgumentException("Dispatcher index should >=0 and <"+this.dispatcherCount);
		}
		return this.dispatchers[index];
	}
	
	public Dispatcher nextDispatcher(){
		return this.dispatchers[this.dispactherIndex.getAndIncrement()%this.dispatcherCount];
	}

	public void registerSession(int ops, Session sess) throws IOException{
		if(sess.dispatcherManager() != this){
			throw new IOException("Unmatched DispatcherManager");
		}
		this.nextDispatcher().registerSession(ops, sess);
	}
	
	
	public Dispatcher getDispatcher(SelectionKey key){
		for(Dispatcher e : this.dispatchers){
			if(key.selector() == e.selector){
				return e;
			}
		}
		return null;
	}
	
	public synchronized void start() {
		if (this.started) {
			return;
		}
		 
		this.started = true;
		for (Dispatcher dispatcher : this.dispatchers) {
			dispatcher.start();
		} 
		log.info("{}(DispatcherCount={}) started", this.dispatcherNamePrefix, this.dispatcherCount);
	}
	
	public synchronized void stop() {
		if (!this.started)
			return;

		this.started = false;
		for (Dispatcher dispatcher : this.dispatchers) {
			dispatcher.interrupt();
		} 
		executor.shutdown();
		log.info("{}(DispatcherCount={}) stopped", this.dispatcherNamePrefix, this.dispatcherCount);
	} 
	 
	public void close() throws IOException {
		this.stop();
	}
	
	public boolean isStarted(){
		return this.started;
	}
	
	public Codec getCodec() {
		return codec;
	} 
	
	public ExecutorService getExecutor() {
		return executor;
	}

 
	public static int defaultDispatcherSize() { 
		int processors = Runtime.getRuntime().availableProcessors();
		return processors > 8 ? 4 + (processors * 5 / 8) : processors + 1;
	}
	
	public static ExecutorService newDefaultExecutor(){
		return new ThreadPoolExecutor(4, 
				256, 120, TimeUnit.SECONDS, new LinkedBlockingQueue());
	} 
	
	public abstract EventAdaptor buildEventAdaptor();
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy