aboutsummaryrefslogtreecommitdiffstats
path: root/container-disc/src/main/java/com/yahoo/container/jdisc/ShutdownDeadline.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-disc/src/main/java/com/yahoo/container/jdisc/ShutdownDeadline.java')
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/ShutdownDeadline.java52
1 files changed, 52 insertions, 0 deletions
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/ShutdownDeadline.java b/container-disc/src/main/java/com/yahoo/container/jdisc/ShutdownDeadline.java
new file mode 100644
index 00000000000..15af216c210
--- /dev/null
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/ShutdownDeadline.java
@@ -0,0 +1,52 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.jdisc;
+
+import com.yahoo.concurrent.DaemonThreadFactory;
+import com.yahoo.vespa.defaults.Defaults;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import static com.yahoo.protect.Process.dumpHeap;
+import static com.yahoo.protect.Process.logAndDie;
+
+/**
+ * Kills the JVM if the application is unable to shutdown before deadline.
+ *
+ * @author bjorncs
+ */
+class ShutdownDeadline implements AutoCloseable {
+
+ private final String configId;
+ private final ScheduledThreadPoolExecutor executor;
+
+ ShutdownDeadline(String configId) {
+ this.configId = configId;
+ executor = new ScheduledThreadPoolExecutor(1, new DaemonThreadFactory("Shutdown deadline timer"));
+ executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+ }
+
+ ShutdownDeadline schedule(long millis, boolean heapdumpOnShutdown) {
+ executor.schedule(() -> onDeadline(heapdumpOnShutdown), millis, TimeUnit.MILLISECONDS);
+ return this;
+ }
+
+ void cancel() { executor.shutdownNow(); }
+ @Override public void close() { cancel(); }
+
+ private void onDeadline(boolean heapdumpOnShutdown) {
+ if (heapdumpOnShutdown) dumpHeap(heapdumpFilename(), true);
+ logAndDie("Timed out waiting for application shutdown. Please check that all your request handlers " +
+ "drain their request content channels.", true);
+ }
+
+ private String heapdumpFilename() {
+ return Defaults.getDefaults().underVespaHome("var/crash/java_pid.") + sanitizeFileName(configId) + "."
+ + ProcessHandle.current().pid() + ".hprof";
+ }
+
+ static String sanitizeFileName(String s) {
+ return s.trim().replace('\\', '.').replaceAll("[/,;]", ".");
+ }
+
+}