package com.yahoo.dtf.debug;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import mx4j.tools.config.DefaultConfigurationBuilder.Shutdown;
import com.yahoo.dtf.NodeShutdownHook;
import com.yahoo.dtf.actions.protocol.deploy.DTFNode;
import com.yahoo.dtf.exception.DTFException;
import com.yahoo.dtf.exception.DebugServerException;
import com.yahoo.dtf.logger.DTFLogger;
public class DebugServer extends Thread implements NodeShutdownHook {
private static DTFLogger _log = DTFLogger.getLogger(DebugServer.class);
private final static int MAX_RETRY = 50;
private static DebugServer _instance = null;
private ServerSocket _serversocket = null;
private boolean _running = true;
private DebugCLI cli = null;
private int port = 40000;
private DebugServer() throws DebugServerException {
com.yahoo.dtf.DTFNode.registerShutdownHook(this);
int retry = 0;
while ( retry < MAX_RETRY ) {
try {
_serversocket = new ServerSocket(port,5);
break;
} catch (IOException e) {
port++;
retry++;
}
}
if ( _serversocket == null )
throw new DebugServerException("Errors binding to server socket.");
_log.info("Listening at 127.0.0.1:" + port);
}
public int getPort() { return port; }
public synchronized static DebugServer getInstance() throws DebugServerException {
if ( _instance == null ) {
_instance = new DebugServer();
_instance.start();
}
return _instance;
}
public static DebugCLI getCLI() { return _instance.cli; }
@Override
public void run() {
while ( _running ) {
Socket clientSocket = null;
try {
clientSocket = _serversocket.accept();
cli = new DebugCLI(clientSocket);
cli.parse();
} catch (IOException e) {
if ( _running )
_log.error("Client connection error.",e);
} catch (DTFException e) {
if ( _running ) {
e.printStackTrace();
cli.writeLine("ERROR: " + e.getMessage());
}
} catch (Throwable t) {
if ( _running ) {
t.printStackTrace();
cli.writeLine("ERROR: " + t.getMessage());
}
} finally {
if ( cli != null )
cli.close();
}
}
}
/**
* Only a single DebugServer running in a given JVM
*
* @throws DebugServerException
*/
public synchronized static void init() throws DebugServerException {
if ( _instance == null ) {
_instance = getInstance();
} else {
throw new DebugServerException("Trying to start DebugServer twice.");
}
}
public void shutdown() {
if ( _instance != null ) {
_instance._running = false;
try {
if ( _instance.cli != null )
_instance.cli.shutdown();
_instance._serversocket.close();
} catch (IOException e) {
_log.error("Issues shutting down server socket.",e);
}
try {
_instance.join();
} catch (InterruptedException ignore) { }
}
}
}