diff --git a/unknow-server-nio/src/main/java/unknow/server/nio/NIOConnection.java b/unknow-server-nio/src/main/java/unknow/server/nio/NIOConnection.java index 0c01a2b6..18982b85 100644 --- a/unknow-server-nio/src/main/java/unknow/server/nio/NIOConnection.java +++ b/unknow-server-nio/src/main/java/unknow/server/nio/NIOConnection.java @@ -324,9 +324,11 @@ private void writeBuffer() throws IOException { } } - private class WriteCheck implements WorkerTask { + private class WriteCheck extends WorkerTask { @Override - public void run(long now) { + protected void run(long now) { + if (!key.isValid()) + return; if (hasPendingWrites()) key.interestOpsOr(SelectionKey.OP_WRITE); else diff --git a/unknow-server-nio/src/main/java/unknow/server/nio/NIOLoop.java b/unknow-server-nio/src/main/java/unknow/server/nio/NIOLoop.java index 11205a94..9154c317 100644 --- a/unknow-server-nio/src/main/java/unknow/server/nio/NIOLoop.java +++ b/unknow-server-nio/src/main/java/unknow/server/nio/NIOLoop.java @@ -53,6 +53,10 @@ public final void start() { t.start(); } + public final boolean isAlive() { + return t.isAlive(); + } + /** * stop the loop */ diff --git a/unknow-server-nio/src/main/java/unknow/server/nio/NIOSSLHandler.java b/unknow-server-nio/src/main/java/unknow/server/nio/NIOSSLHandler.java index 6c5285cf..90913ee9 100644 --- a/unknow-server-nio/src/main/java/unknow/server/nio/NIOSSLHandler.java +++ b/unknow-server-nio/src/main/java/unknow/server/nio/NIOSSLHandler.java @@ -164,7 +164,7 @@ private boolean checkHandshake(HandshakeStatus hs, long now) throws IOException } } - private final class RunTask implements Runnable, WorkerTask { + private final class RunTask extends WorkerTask implements Runnable { @Override public void run() { logger.trace("start task"); @@ -175,7 +175,7 @@ public void run() { } @Override - public void run(long now) { + protected void run(long now) { logger.trace("resume handshake"); try { checkHandshake(sslEngine.getHandshakeStatus(), now); diff --git a/unknow-server-nio/src/main/java/unknow/server/nio/NIOWorker.java b/unknow-server-nio/src/main/java/unknow/server/nio/NIOWorker.java index 944bc6a6..9d96d3e7 100644 --- a/unknow-server-nio/src/main/java/unknow/server/nio/NIOWorker.java +++ b/unknow-server-nio/src/main/java/unknow/server/nio/NIOWorker.java @@ -70,6 +70,7 @@ public NIOWorker(int id, ExecutorService executor, NIOServerListener listener, l } protected final void execute(WorkerTask task) { + listener.accepted(name, task); tasks.add(task); selector.wakeup(); } @@ -99,8 +100,10 @@ public Collection workers() { @Override protected void onSelect(long now, boolean close) { WorkerTask r; - while ((r = tasks.poll()) != null) - r.run(now); + while ((r = tasks.poll()) != null) { + r.work(now); + listener.done(name, r); + } checkPending(now, close); finishClosing(now); @@ -227,7 +230,7 @@ public final Future submit(Runnable r) { private void startClose(NIOConnection co, long now) { if (!remove(co)) return; - logger.debug("{} start closing", co); + listener.closing(name, co); closing.add(co); co.startClose(now); } @@ -250,8 +253,21 @@ protected int nbTask() { return tasks.size(); } - public static interface WorkerTask { - void run(long now); + public static class WorkerTask { + final void work(long now) { + try { + run(now); + } catch (Exception e) { + error(e, now); + } + } + + protected void run(@SuppressWarnings("unused") long now) { // ok + } + + protected void error(Exception e, @SuppressWarnings("unused") long now) { // ok + logger.warn("Error on task {}", this, e); + } } private final void unlink(NIOConnection co) { @@ -291,7 +307,7 @@ private final void toTail(NIOConnection co, long now) { head = co; } - private final class RegisterTask implements WorkerTask { + private final class RegisterTask extends WorkerTask { private final SelectionKey key; private final ConnectionFactory factory; @@ -301,7 +317,7 @@ public RegisterTask(SelectionKey key, ConnectionFactory factory) { } @Override - public void run(long now) { + protected void run(long now) { NIOConnection co = new NIOConnection(NIOWorker.this, key, factory.build()); key.attach(co); listener.accepted(name, co); @@ -318,6 +334,12 @@ public void run(long now) { submit(new AsyncInit(co)); toTail(co, now); } + + @Override + protected void error(Exception e, long now) { + logger.warn("Failed to register key {}", key, e); + key.cancel(); + } } private static final class AsyncInit implements Runnable {