Skip to content

Commit

Permalink
Arc - Make it possible to inspect shutdown reason from ShutdownEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
manovotn committed Jul 15, 2022
1 parent 10ecfc8 commit 7f149aa
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
*/
public class ApplicationLifecycleManager {

// used by ShutdownEvent to propagate the information about shutdown reason
public static volatile ShutdownEvent.ShutdownReason shutdownReason = ShutdownEvent.ShutdownReason.STANDARD;
private static volatile BiConsumer<Integer, Throwable> defaultExitCodeHandler = new BiConsumer<Integer, Throwable>() {
@Override
public void accept(Integer integer, Throwable cause) {
Expand Down Expand Up @@ -408,6 +410,8 @@ public void run() {
//we let the application main thread take care of actually exiting
//TODO: if the main thread is not actively waiting to exit should we interrupt it?
shutdownRequested = true;
// so long as this thread is invoked, the app shutdown is considered non-standard
shutdownReason = ShutdownEvent.ShutdownReason.NON_STANDARD;
try {
stateCond.signalAll();
} finally {
Expand Down
42 changes: 41 additions & 1 deletion core/runtime/src/main/java/io/quarkus/runtime/ShutdownEvent.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package io.quarkus.runtime;

/**
* Event that is fired before shutdown.
* Event that is fired before shutdown and can be inspected for shutdown cause.
* See {@link ShutdownEvent#isStandardShutdown()}
*
* This event is observed as follows:
*
Expand All @@ -14,4 +15,43 @@
* The annotated method can access other injected beans.
*/
public class ShutdownEvent {

private ShutdownReason shutdownReason;

public ShutdownEvent() {
this.shutdownReason = ShutdownReason.STANDARD;
}

public ShutdownEvent(ShutdownReason shutdownReason) {
this.shutdownReason = shutdownReason;
}

/**
* Returns {@code true} if the application shutdown is considered standard; i.e. by exiting {@code main()} method or
* executing either {@link Quarkus#asyncExit()} or {@link Quarkus#blockingExit()}.
* <p>
* All other cases are non-standard - {@code SIGINT}, {@code SIGTERM}, {@code System.exit(n} and so on.
* Sending {@code CTRL + C} to running app in terminal is also non-standard shutdown.
*
* @return true if the app shutdown was standard, false otherwise
*/
public boolean isStandardShutdown() {
return shutdownReason.equals(ShutdownReason.STANDARD);
}

/**
* An enum with values reflecting the reason for application shutdown.
*/
enum ShutdownReason {
/**
* When {@code main()} method exits or when either {@link Quarkus#asyncExit()} or
* {@link Quarkus#blockingExit()} was executed
*/
STANDARD,
/**
* All other cases - {@code SIGINT}, {@code SIGTERM}, {@code System.exit(n} and so on.
* This includes sending {@code CTRL + C} to running app in terminal.
*/
NON_STANDARD;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.quarkus.arc.InjectableBean.Kind;
import io.quarkus.arc.impl.ArcContainerImpl;
import io.quarkus.arc.runtime.test.PreloadedTestApplicationClassPredicate;
import io.quarkus.runtime.ApplicationLifecycleManager;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.ShutdownContext;
Expand Down Expand Up @@ -101,7 +102,7 @@ public void handleLifecycleEvents(ShutdownContext context, LaunchMode launchMode
context.addShutdownTask(new Runnable() {
@Override
public void run() {
fireLifecycleEvent(container, new ShutdownEvent(), mockBeanClasses);
fireLifecycleEvent(container, new ShutdownEvent(ApplicationLifecycleManager.shutdownReason), mockBeanClasses);
}
});
}
Expand Down

0 comments on commit 7f149aa

Please sign in to comment.