package dslab.rmi.stub; import dslab.protocol.Protocol; import dslab.protocol.ProtocolException; import dslab.rmi.channel.SocketChannel; import dslab.rmi.serialize.IllegalCommandException; import dslab.rmi.serialize.ServerSerializer; import java.nio.channels.ClosedChannelException; import java.util.logging.Logger; import static java.lang.Thread.currentThread; import static java.util.logging.Level.INFO; public abstract class ServerStub<PROTOCOL extends Protocol> implements Runnable { private final PROTOCOL protocol; private final SocketChannel channel; private final ServerSerializer<PROTOCOL> serializer; private final Logger LOG = Logger.getLogger(getClass().getSimpleName()); public ServerStub(SocketChannel channel, ServerSerializer<PROTOCOL> serializer, PROTOCOL protocol) { this.channel = channel; this.protocol = protocol; this.serializer = serializer; LOG.info("Init " + getClass().getSimpleName() + " with " + this.channel + " aka " + this.channel.getId()); } @Override public void run() { try { try (channel) { channel.write(serializer.serialize(protocol)); while (!currentThread().isInterrupted()) { try { var result = serializer.deserialize(channel.readLinesWhileReady()).apply(protocol); channel.write(serializer.serialize(result)); } catch (ProtocolException e) { channel.write(serializer.serialize(e)); if (e instanceof IllegalCommandException) { LOG.log(INFO, e.getMessage() + " - Closing connection."); break; } } } } finally { afterSession(); } } catch (ClosedChannelException ignored) {} //Break out of while if client terminates connection } protected abstract void afterSession(); }