Skip to content

Commit 3f93509

Browse files
authored
Merge pull request #1371 from myronkscott/fix_galvan2
fix thread shutdown issues
2 parents ec701ee + be7c127 commit 3f93509

File tree

10 files changed

+140
-148
lines changed

10 files changed

+140
-148
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dependency-reduced-pom.xml
1010

1111
*.iml
1212
.idea/
13-
/bin/
13+
**/bin/
1414
*~
1515
nb-configuration.xml
1616
nbactions.xml

common/src/main/java/com/tc/lang/TCThreadGroup.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public TCThreadGroup(ThrowableHandler throwableHandler, String name) {
4646
}
4747

4848
public TCThreadGroup(ThrowableHandler throwableHandler, String name, boolean stoppable) {
49-
this(throwableHandler, name, stoppable, stoppable);
49+
this(throwableHandler, name, stoppable, !stoppable);
5050
}
5151

5252
public TCThreadGroup(ThrowableHandler throwableHandler, String name, boolean stoppable, boolean ignorePool) {
@@ -81,10 +81,6 @@ public void printLiveThreads(Consumer<String> reporter) {
8181
}
8282
}
8383

84-
public void interruptThreads() {
85-
threads().stream().filter(t -> t != Thread.currentThread() && t.isAlive()).forEach(Thread::interrupt);
86-
}
87-
8884
public boolean retire(long timeout, Consumer<InterruptedException> interruptHandler) {
8985
boolean complete = false;
9086
long killStart = System.currentTimeMillis();
@@ -97,9 +93,8 @@ public boolean retire(long timeout, Consumer<InterruptedException> interruptHand
9793
}
9894
}
9995
}
100-
if (activeCount() == 0) {
101-
destroy();
102-
}
96+
} else {
97+
return true;
10398
}
10499
if (complete) {
105100
LOGGER.debug("finished thread exiting in {} seconds", TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - killStart));

common/src/main/java/com/tc/util/concurrent/LifeCycleState.java

Lines changed: 0 additions & 30 deletions
This file was deleted.

common/src/main/java/com/tc/util/concurrent/NullLifeCycleState.java

Lines changed: 0 additions & 41 deletions
This file was deleted.

galvan/src/main/java/org/terracotta/testing/master/InlineServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ private synchronized boolean initializeServer(OutputStream out) throws Exception
238238
public synchronized boolean shutdown() {
239239
if (running) {
240240
running = false;
241-
String result = invokeOnServerMBean(server, "Server","stopAndWait",null);
241+
String result = invokeOnServerMBean(server, "Server","halt",null);
242242
serverLogger.output("stopping. " + result);
243243
return !Boolean.parseBoolean(result);
244244
} else {

management/src/main/java/com/tc/management/beans/TCServerInfoMBean.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public interface TCServerInfoMBean extends TerracottaMBean, RuntimeStatisticCons
4343

4444
boolean stopAndWait();
4545

46+
boolean halt();
47+
4648
boolean isShutdownable();
4749

4850
void shutdown();

tc-server/src/main/java/com/tc/management/beans/TCServerInfo.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import javax.management.MBeanNotificationInfo;
5858
import javax.management.NotCompliantMBeanException;
5959
import org.terracotta.server.ServerEnv;
60+
import org.terracotta.server.StopAction;
6061

6162
public class TCServerInfo extends AbstractTerracottaMBean implements TCServerInfoMBean, StateChangeListener {
6263
private static final Logger logger = LoggerFactory.getLogger(TCServerInfo.class);
@@ -156,6 +157,12 @@ public boolean stopAndWait() {
156157
return server.waitUntilShutdown();
157158
}
158159

160+
@Override
161+
public boolean halt() {
162+
server.stop(StopAction.IMMEDIATE);
163+
return server.waitUntilShutdown();
164+
}
165+
159166
@Override
160167
public boolean isShutdownable() {
161168
return server.canShutdown();

tc-server/src/main/java/com/tc/objectserver/impl/DistributedObjectServer.java

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -869,26 +869,19 @@ public synchronized void openNetworkPorts() throws ConfigurationException {
869869

870870
public CompletableFuture<Void> destroy(boolean immediate) throws Exception {
871871
CompletableFuture<Void> finished = new CompletableFuture<>();
872-
if (this.threadGroup.isStoppable()) {
873-
if (this.stopping.attemptSet()) {
872+
if (!immediate) {
873+
try {
874+
stopped.get();
875+
} catch (ExecutionException ee) {
876+
finished.completeExceptionally(ee.getCause());
877+
return finished;
878+
}
879+
}
880+
if (this.stopping.attemptSet() && this.threadGroup.isStoppable()) {
874881
ThreadUtil.executeInThread(threadGroup.getParent(), ()->{
875-
try {
876-
if (!immediate) {
877-
try {
878-
stopped.get();
879-
} catch (ExecutionException ee) {
880-
logger.warn("stop not complete", ee.getCause());
881-
}
882-
}
883-
killThreads(finished, immediate);
884-
}catch(InterruptedException ie) {
885-
logger.warn("shutdown thread failed", ie);
886-
finished.completeExceptionally(ie);
887-
}
882+
killThreads(finished);
888883
}, "server shutdown thread", true);
889-
}
890884
} else {
891-
consoleLogger.info("Server Exiting...");
892885
finished.complete(null);
893886
}
894887
return finished;
@@ -911,17 +904,14 @@ private void shutdown() {
911904
}
912905
}
913906

914-
private void killThreads(CompletableFuture<Void> stopped, boolean immediate) {
907+
private void killThreads(CompletableFuture<Void> stopped) {
915908
try {
916909
this.seda.getStageManager().stopAll();
917-
if (immediate) {
918-
threadGroup.interrupt();
919-
} else if (!threadGroup.retire(TimeUnit.SECONDS.toMillis(30L), e->L2Utils.handleInterrupted(logger, e))) {
910+
while (!threadGroup.retire(TimeUnit.SECONDS.toMillis(10L), e->L2Utils.handleInterrupted(logger, e))) {
920911
consoleLogger.warn("unable to retire server threads");
921912
threadGroup.printLiveThreads(logger::warn);
922913
threadGroup.interrupt();
923914
}
924-
consoleLogger.info("Server Exiting...");
925915
} finally {
926916
stopped.complete(null);
927917
}

tc-server/src/main/java/com/tc/server/TCServerImpl.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import javax.management.NotCompliantMBeanException;
6060
import com.tc.text.PrettyPrinter;
6161
import java.lang.management.ManagementFactory;
62+
import java.util.Arrays;
6263
import java.util.EnumSet;
6364
import java.util.List;
6465
import java.util.Map;
@@ -144,24 +145,26 @@ public void stopIfActive(StopAction...restartMode) throws PlatformStopException
144145
@Override
145146
public void stop(StopAction...restartMode) {
146147
audit("Stop invoked", new Properties());
147-
TCLogging.getConsoleLogger().info("Stopping server");
148148
if (dsoServer != null) {
149149
try {
150-
getStateManager().moveToStopStateIf(EnumSet.complementOf(EnumSet.of(ServerMode.STOP)));
151-
EnumSet<StopAction> set = EnumSet.noneOf(StopAction.class);
152-
for (StopAction s : restartMode) {
153-
set.add(s);
154-
}
155-
if (set.contains(StopAction.ZAP)) {
156-
TCLogging.getConsoleLogger().info("Setting data to dirty");
157-
dsoServer.getPersistor().getClusterStatePersistor().setDBClean(false);
158-
}
159-
CompletableFuture<Void> dsoStop = dsoServer.destroy(set.contains(StopAction.IMMEDIATE));
160-
if (set.contains(StopAction.RESTART)) {
161-
TCLogging.getConsoleLogger().info("Requesting restart");
162-
dsoStop.thenRun(()->shutdownGate.complete(true));
163-
} else {
164-
dsoStop.thenRun(()->shutdownGate.complete(false));
150+
if (getStateManager().moveToStopStateIf(EnumSet.complementOf(EnumSet.of(ServerMode.STOP)))) {
151+
consoleLogger.info("Stopping server");
152+
EnumSet<StopAction> set = EnumSet.noneOf(StopAction.class);
153+
set.addAll(Arrays.asList(restartMode));
154+
if (set.contains(StopAction.ZAP)) {
155+
TCLogging.getConsoleLogger().info("Setting data to dirty");
156+
dsoServer.getPersistor().getClusterStatePersistor().setDBClean(false);
157+
}
158+
CompletableFuture<Void> dsoStop = dsoServer.destroy(set.contains(StopAction.IMMEDIATE));
159+
dsoStop = dsoStop.thenRun(()->{
160+
consoleLogger.info("Server Exiting...");
161+
});
162+
if (set.contains(StopAction.RESTART)) {
163+
TCLogging.getConsoleLogger().info("Requesting restart");
164+
dsoStop.thenRun(()->shutdownGate.complete(true));
165+
} else {
166+
dsoStop.thenRun(()->shutdownGate.complete(false));
167+
}
165168
}
166169
} catch (Throwable e) {
167170
logger.error("trouble shutting down", e);
@@ -198,7 +201,6 @@ public boolean canShutdown() {
198201
@Override
199202
public synchronized void shutdown() {
200203
if (canShutdown()) {
201-
consoleLogger.info("Server exiting...");
202204
stop();
203205
} else {
204206
logger.warn("Server in incorrect state (" + getStateManager().getCurrentMode().getName() + ") to be shutdown.");

0 commit comments

Comments
 (0)