Fixed YaCy proper shutdown triggered by SIGTERM signal.

The main shutdown hook thread was not properly waiting for the main
thread termination which consequently could not properly close resources
and threads. After terminating a running YaCy peer this way (Ctrl+C in
console, or kill <pid> for example), you could see the still existing
DATA/yacy.running file.

Tested with :
 - Debian Jessie openjdk 7 and 8 : regular shutdown, Ctrl+C, kill
command, system restart while yacy is running
 - Windows 10 Oracle JDK 7 and 8 : non regression on regular shutdown
pull/97/merge
luccioman 8 years ago
parent fce701f5cc
commit 1df558a6c6

@ -1872,6 +1872,10 @@ public final class Switchboard extends serverSwitch {
public synchronized void close() {
this.log.config("SWITCHBOARD SHUTDOWN STEP 1: sending termination signal to managed threads:");
/* Print also to the standard output : when this method is triggered by the shutdown hook thread, the LogManager is likely to have
* been concurrently reset by its own shutdown hook thread */
System.out.println("SWITCHBOARD Performing shutdown steps...");
MemoryTracker.stopSystemProfiling();
terminateAllThreads(true);
net.yacy.gui.framework.Switchboard.shutdown();
@ -1915,6 +1919,9 @@ public final class Switchboard extends serverSwitch {
ConcurrentLog.logException(e);
}
this.log.config("SWITCHBOARD SHUTDOWN TERMINATED");
/* Print also to the standard output : when this method is triggered by the shutdown hook thread, the LogManager is likely to have
* been concurrently reset by its own shutdown hook thread */
System.out.println("SWITCHBOARD Shutdown steps terminated.");
}
/**

@ -41,6 +41,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import com.google.common.io.Files;
@ -50,7 +51,6 @@ import net.yacy.cora.federate.yacy.CacheStrategy;
import net.yacy.cora.order.Digest;
import net.yacy.cora.protocol.ClientIdentification;
import net.yacy.cora.protocol.ConnectionInfo;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.protocol.TimeoutRequest;
import net.yacy.cora.protocol.http.HTTPClient;
import net.yacy.cora.sorting.Array;
@ -365,7 +365,7 @@ public final class yacy {
// registering shutdown hook
ConcurrentLog.config("STARTUP", "Registering Shutdown Hook");
final Runtime run = Runtime.getRuntime();
run.addShutdownHook(new shutdownHookThread(Thread.currentThread(), sb));
run.addShutdownHook(new shutdownHookThread(sb, shutdownSemaphore));
// save information about available memory after all initializations
//try {
@ -784,12 +784,12 @@ public final class yacy {
*/
class shutdownHookThread extends Thread {
private final Switchboard sb;
private final Thread mainThread;
private final Semaphore shutdownSemaphore;
public shutdownHookThread(final Thread mainThread, final Switchboard sb) {
public shutdownHookThread(final Switchboard sb, final Semaphore shutdownSemaphore) {
super("yacy.shutdownHookThread");
this.sb = sb;
this.mainThread = mainThread;
this.shutdownSemaphore = shutdownSemaphore;
}
@Override
@ -797,6 +797,9 @@ class shutdownHookThread extends Thread {
try {
if (!this.sb.isTerminated()) {
ConcurrentLog.config("SHUTDOWN","Shutdown via shutdown hook.");
/* Print also to the standard output, as the LogManager is likely to have
* been concurrently reset by its own shutdown hook thread */
System.out.println("SHUTDOWN Starting shutdown via shutdown hook.");
// sending the yacy main thread a shutdown signal
ConcurrentLog.fine("SHUTDOWN","Signaling shutdown to the switchboard.");
@ -804,9 +807,10 @@ class shutdownHookThread extends Thread {
// waiting for the yacy thread to finish execution
ConcurrentLog.fine("SHUTDOWN","Waiting for main thread to finish.");
if (this.mainThread.isAlive() && !this.sb.isTerminated()) {
this.mainThread.join();
}
/* Main thread will release the shutdownSemaphore once completely terminated.
* We do not wait indefinitely as the application is supposed here to quickly terminate */
this.shutdownSemaphore.tryAcquire(30, TimeUnit.SECONDS);
}
} catch (final Exception e) {
ConcurrentLog.severe("SHUTDOWN","Unexpected error. " + e.getClass().getName(),e);

Loading…
Cancel
Save