diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/ResultConsumer.java b/core/src/main/java/com/taobao/arthas/core/distribution/ResultConsumer.java index 528c80033..eaa338280 100644 --- a/core/src/main/java/com/taobao/arthas/core/distribution/ResultConsumer.java +++ b/core/src/main/java/com/taobao/arthas/core/distribution/ResultConsumer.java @@ -24,6 +24,10 @@ public interface ResultConsumer { long getLastAccessTime(); + void close(); + + boolean isClosed(); + boolean isPolling(); String getConsumerId(); diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/ResultDistributor.java b/core/src/main/java/com/taobao/arthas/core/distribution/ResultDistributor.java index b73960099..5b6711bf7 100644 --- a/core/src/main/java/com/taobao/arthas/core/distribution/ResultDistributor.java +++ b/core/src/main/java/com/taobao/arthas/core/distribution/ResultDistributor.java @@ -14,4 +14,8 @@ public interface ResultDistributor { */ void appendResult(ResultModel result); + /** + * Close result distribtor, release resources + */ + void close(); } diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/impl/PackingResultDistributorImpl.java b/core/src/main/java/com/taobao/arthas/core/distribution/impl/PackingResultDistributorImpl.java index af81c4ffa..9903b8e48 100644 --- a/core/src/main/java/com/taobao/arthas/core/distribution/impl/PackingResultDistributorImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/distribution/impl/PackingResultDistributorImpl.java @@ -29,6 +29,10 @@ public class PackingResultDistributorImpl implements PackingResultDistributor { } } + @Override + public void close() { + } + @Override public List getResults() { ArrayList results = new ArrayList(resultQueue.size()); diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/impl/ResultConsumerImpl.java b/core/src/main/java/com/taobao/arthas/core/distribution/impl/ResultConsumerImpl.java index 2e5a004ef..0997936e7 100644 --- a/core/src/main/java/com/taobao/arthas/core/distribution/impl/ResultConsumerImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/distribution/impl/ResultConsumerImpl.java @@ -26,6 +26,7 @@ public class ResultConsumerImpl implements ResultConsumer { private int resultSizeLimit = 100; private long pollTimeLimit = 10 * 1000; private String consumerId; + private boolean closed; public ResultConsumerImpl() { lastAccessTime = System.currentTimeMillis(); @@ -51,7 +52,8 @@ public class ResultConsumerImpl implements ResultConsumer { long waitingTime = 0; List sendingResults = new ArrayList(resultSizeLimit); - while (sendingResults.size() < resultSizeLimit + while (!closed + &&sendingResults.size() < resultSizeLimit && sendingDelay < 200 && waitingTime < pollTimeLimit) { ResultModel aResult = resultQueue.poll(100, TimeUnit.MILLISECONDS); @@ -92,6 +94,16 @@ public class ResultConsumerImpl implements ResultConsumer { return lastAccessTime; } + @Override + public void close(){ + this.closed = true; + } + + @Override + public boolean isClosed() { + return closed; + } + @Override public boolean isPolling() { return polling; diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java b/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java index b68c9c388..edc66d7fb 100644 --- a/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/distribution/impl/SharingResultDistributorImpl.java @@ -62,6 +62,11 @@ public class SharingResultDistributorImpl implements SharingResultDistributor { } } + @Override + public void close() { + this.running = false; + } + @Override public void addConsumer(ResultConsumer consumer) { int consumerNo = consumerNumGenerator.incrementAndGet(); @@ -77,6 +82,7 @@ public class SharingResultDistributorImpl implements SharingResultDistributor { @Override public void removeConsumer(ResultConsumer consumer) { consumers.remove(consumer); + consumer.close(); } @Override @@ -153,6 +159,16 @@ public class SharingResultDistributorImpl implements SharingResultDistributor { return 0; } + @Override + public void close() { + + } + + @Override + public boolean isClosed() { + return false; + } + @Override public boolean isPolling() { return false; diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java b/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java index 393e28d29..c47d69e04 100644 --- a/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java @@ -29,4 +29,8 @@ public class TermResultDistributorImpl implements ResultDistributor { } } + @Override + public void close() { + } + } diff --git a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java index 2cf6a442e..da0509b96 100644 --- a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java +++ b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java @@ -73,6 +73,7 @@ public class ArthasBootstrap { private File arthasOutputDir; private static LoggerContext loggerContext; + private EventExecutorGroup workerGroup; private ArthasBootstrap(Instrumentation instrumentation, String args) throws Throwable { this.instrumentation = instrumentation; @@ -269,7 +270,7 @@ public class ArthasBootstrap { resolvers.add(builtinCommands); //worker group - EventExecutorGroup workerGroup = new NioEventLoopGroup(8); + workerGroup = new NioEventLoopGroup(24); // TODO: discover user provided command resolver if (configure.getTelnetPort() > 0) { @@ -313,10 +314,18 @@ public class ArthasBootstrap { if (sessionManager != null){ sessionManager.close(); } + shutdownWorkGroup(); throw e; } } + private void shutdownWorkGroup() { + if (workerGroup != null) { + workerGroup.shutdownGracefully(200, 200, TimeUnit.MILLISECONDS); + workerGroup = null; + } + } + /** * 判断服务端是否已经启动 * @@ -336,6 +345,7 @@ public class ArthasBootstrap { } executorService.shutdownNow(); UserStatUtil.destroy(); + shutdownWorkGroup(); // clear the reference in Spy class. cleanUpSpyReference(); try { @@ -347,6 +357,8 @@ public class ArthasBootstrap { if (loggerContext != null) { loggerContext.stop(); } + shellServer = null; + sessionManager = null; } /** diff --git a/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java index 303cfb5f2..494984560 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java @@ -93,7 +93,9 @@ public class SessionManagerImpl implements SessionManager { ArrayList sessions = new ArrayList(this.sessions.values()); for (Session session : sessions) { - session.getResultDistributor().appendResult(new MessageModel("arthas server is going to shutdown.")); + SharingResultDistributor resultDistributor = session.getResultDistributor(); + resultDistributor.appendResult(new MessageModel("arthas server is going to shutdown.")); + resultDistributor.close(); logger.info("Removing session before shutdown: {}, last access time: {}", session.getSessionId(), session.getLastAccessTime()); this.removeSession(session.getSessionId()); }