Reputation: 81
I'm not sure what exactly the problem is with shutting down my Server (and ExecutorService). I start the ServerMain and press enter, which starts the server.shutdown() method with socket.close() but it doesn't throw a SocketException. I don't know if this is related to the ExecutorService not being able to shutdown though. This is the code:
public class ServerMain {
public static void main(String[] args) throws DirectoryServerException, IOException {
TCPDirectoryServer server = new TCPDirectoryServer();
ExecutorService serverExecutor = Executors.newSingleThreadExecutor();
try {
server.start(1337);
serverExecutor.execute(server);
System.out.println("Server started. Press enter to terminate.");
System.in.read();
server.shutdown();
System.out.println("Server is shut down...");
} finally {
serverExecutor.shutdown();
while (!serverExecutor.isTerminated()) {
try {
if (!serverExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
System.err.println("Problem with shutting down the Executor");
serverExecutor.shutdownNow();
}
} catch (InterruptedException ignore) {
}
}
}
}
}
And here's the server:
public class TCPDirectoryServer implements DirectoryServer {
private int port;
private ConcurrentHashMap<ParseDirectory, Histogram> cache;
private List<ClientHandler> clientHandlerList;
private ExecutorService clientExecutorService;
private Socket socket;
public TCPDirectoryServer() {
super();
this.cache = new ConcurrentHashMap<ParseDirectory, Histogram>();
this.clientHandlerList = new LinkedList<ClientHandler>();
this.clientExecutorService = Executors.newCachedThreadPool();
}
@Override
public void start(int port) throws DirectoryServerException {
this.port = port;
}
@Override
public void disconnect(ClientHandler clientHandler) {
clientHandlerList.remove(clientHandler);
}
@Override
public void shutdown() throws DirectoryServerException {
try {
socket.close();
} catch (IOException e) {
throw new DirectoryServerException(e);
}
}
@Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (true) {
socket = serverSocket.accept();
clientHandlerList.add(connect(socket));
}
} catch (SocketException e) {
System.err.println("AAAA");
System.out.println("Server is shutting down");
} catch (IOException e) {
System.out.println("Something failed " + e.getMessage());
}
}
Upvotes: 0
Views: 628
Reputation: 43
In your TCPDirectoryServer class make serverSocket a member variable and your shutdown method should look like the following
public void shutdown() {
......
this.serverSocket.close();
........
}
Also when closing a client socket(s) watch out for NPE if the socket is null (no one connected to your server). This will also prevent your server from shutting down.
Upvotes: 0
Reputation: 1690
Calling the serverExecutor.shutdown() will still cause the server to wait for all processes to finish before shutting down. It's a gracefully shutdown. It is probably waiting on the "while(true)" loop to exit, which it doesn't look like it ever will. Try calling serverExecutor.shutdownNow(); to terminate your program.
Upvotes: 0
Reputation: 8044
This part:
while (true) {
socket = serverSocket.accept();
clientHandlerList.add(connect(socket));
}
...won't throw a SocketException when you call shutdown
, because you're closing a client socket there (the one that last connected). The ServerSocket is still open and waiting for incoming requests.
Upvotes: 2