package org.jboss.pitbull.server;
import org.jboss.pitbull.internal.logging.Logger;
import org.jboss.pitbull.internal.nio.http.HttpConnector;
import org.jboss.pitbull.internal.nio.socket.Worker;
import org.jboss.pitbull.internal.util.registry.UriRegistry;
import org.jboss.pitbull.server.spi.RequestHandler;
import org.jboss.pitbull.server.spi.RequestInitiator;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class HttpServer
{
protected UriRegistry<Object> registry = new UriRegistry<Object>();
protected static final Logger logger = Logger.getLogger(HttpServer.class);
protected ExecutorService acceptorExecutor;
protected ExecutorService requestExecutor;
protected ExecutorService workerExecutor;
protected Worker[] workers;
protected int numWorkers;
protected List<HttpConnector> connectors = new ArrayList<HttpConnector>();
/**
* Metrics of accepted connections
*
* @return
*/
public long getAcceptCount()
{
long count = 0;
for (HttpConnector connector : connectors)
{
count += connector.getAcceptCount();
}
return count;
}
/**
* Metric of accepted connection distribution onto workers
*
* @return
*/
public long[] getWorkerRegistrationDistribution()
{
long[] dist = new long[workers.length];
for (int i = 0; i < dist.length; i++)
{
dist[i] = workers[i].getNumRegistered();
}
return dist;
}
/**
* @return
*/
public void clearMetrics()
{
for (HttpConnector connector : connectors)
{
connector.clearMetrics();
}
for (Worker worker : workers)
{
worker.clearMetrics();
}
}
public List<HttpConnector> getConnectors()
{
return connectors;
}
public ExecutorService getAcceptorExecutor()
{
return acceptorExecutor;
}
public void setAcceptorExecutor(ExecutorService acceptorExecutor)
{
this.acceptorExecutor = acceptorExecutor;
}
public ExecutorService getRequestExecutor()
{
return requestExecutor;
}
public int getNumWorkers()
{
return numWorkers;
}
public void setNumWorkers(int numWorkers)
{
this.numWorkers = numWorkers;
}
public void setRequestExecutor(ExecutorService requestExecutor)
{
this.requestExecutor = requestExecutor;
}
public ExecutorService getWorkerExecutor()
{
return workerExecutor;
}
public void setWorkerExecutor(ExecutorService workerExecutor)
{
this.workerExecutor = workerExecutor;
}
public void register(String mappingPattern, RequestHandler handler)
{
registry.register(mappingPattern, handler);
}
public void register(String mappingPattern, RequestInitiator initiator)
{
registry.register(mappingPattern, initiator);
}
public void unregister(RequestHandler handler)
{
registry.unregister(handler);
}
public void unregister(RequestInitiator initiator)
{
registry.unregister(initiator);
}
public void start() throws Exception
{
workers = new Worker[numWorkers];
for (int i = 0; i < workers.length; i++)
{
workers[i] = new Worker();
workerExecutor.execute(workers[i]);
}
for (HttpConnector connector : connectors)
{
connector.setRegistry(registry);
connector.start(workers, acceptorExecutor, requestExecutor);
}
}
public void stop() throws Exception
{
for (HttpConnector connector : connectors)
{
connector.shutdownAcceptor();
}
acceptorExecutor.shutdown();
boolean awaitedAcceptor = acceptorExecutor.awaitTermination(60, TimeUnit.SECONDS);
logger.trace("Shutdown Acceptor Threads: {0}", awaitedAcceptor);
for (Worker worker : workers)
{
worker.shutdown();
}
logger.trace("Shutdown Workers");
workerExecutor.shutdown();
boolean awaitedWorker = workerExecutor.awaitTermination(60, TimeUnit.SECONDS);
logger.trace("Shutdown Worker Executor: {0}", awaitedWorker);
requestExecutor.shutdown();
boolean awaited = requestExecutor.awaitTermination(60, TimeUnit.SECONDS);
logger.trace("Shutdown Request Executor: {0}", awaited);
if (awaited == false) requestExecutor.shutdownNow();
for (Worker worker : workers)
{
worker.close();
}
logger.trace("Closed all workers");
for (HttpConnector connector : connectors)
{
connector.shutdownChannel();
}
logger.trace("Closed channels");
}
}