/**
* The Acceptor thread body.
*/
@Override
public void run() {
final ServiceDispatcher serviceDispatcher =
repNode.getServiceDispatcher();
serviceDispatcher.register(SERVICE_NAME, channelQueue);
LoggerUtils.logMsg
(logger, envImpl, formatter, Level.FINE, "Acceptor started");
SocketChannel channel = null;
try {
while (true) {
channel = serviceDispatcher.takeChannel
(SERVICE_NAME, true /* block */,
protocol.getReadTimeout());
if (channel == null) {
/* A soft shutdown. */
return;
}
final Socket socket = channel.socket();
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader
(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
String requestLine = in.readLine();
if (requestLine == null) {
LoggerUtils.logMsg(logger, envImpl,
formatter, Level.FINE,
"Acceptor: EOF on request");
continue;
}
RequestMessage requestMessage = null;
try {
requestMessage = protocol.parseRequest(requestLine);
} catch (InvalidMessageException e) {
LoggerUtils.logMsg(logger, envImpl,
formatter, Level.WARNING,
"Message format error: " +
e.getMessage());
out.println
(protocol.new ProtocolError(e).wireFormat());
continue;
}
ResponseMessage responseMessage = null;
if (requestMessage.getOp() == protocol.PROPOSE) {
responseMessage = process((Propose) requestMessage);
} else if (requestMessage.getOp() == protocol.ACCEPT) {
responseMessage = process((Accept) requestMessage);
} else if (requestMessage.getOp() == protocol.SHUTDOWN) {
break;
} else {
LoggerUtils.logMsg(logger, envImpl,
formatter, Level.SEVERE,
"Unrecognized request: " +
requestLine);
continue;
}
/*
* The request message may be of an earlier version. If so,
* this node transparently read the older version. JE only
* throws out InvalidMesageException when the version of
* the request message is newer than the current protocol.
* To avoid sending a repsonse that the requester cannot
* understand, we send a response in the same version as
* that of the original request message.
*/
responseMessage.setSendVersion
(requestMessage.getSendVersion());
out.println(responseMessage.wireFormat());
} catch (IOException e) {
LoggerUtils.logMsg
(logger, envImpl, formatter, Level.WARNING,
"IO error on socket: " + e.getMessage());
continue;
} finally {
Utils.cleanup(logger, envImpl, formatter, socket, in, out);
cleanup();
}
}
} catch (InterruptedException e) {
if (isShutdown()) {
/* Treat it like a shutdown, exit the thread. */
return;
}
LoggerUtils.logMsg(logger, envImpl, formatter, Level.WARNING,
"Acceptor unexpected interrupted");
throw EnvironmentFailureException.unexpectedException(e);
} finally {
serviceDispatcher.cancel(SERVICE_NAME);
cleanup();
}
}