|
|
|
@ -714,22 +714,20 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private class CracResourceAdapter implements org.crac.Resource { |
|
|
|
private class CracResourceAdapter implements org.crac.Resource { |
|
|
|
|
|
|
|
|
|
|
|
private @Nullable CyclicBarrier barrier; |
|
|
|
private CyclicBarrier stepToRestore = new CyclicBarrier(2); |
|
|
|
|
|
|
|
private CyclicBarrier finishRestore = new CyclicBarrier(2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void preventShutdown() { |
|
|
|
|
|
|
|
waitBarrier(this.stepToRestore); |
|
|
|
|
|
|
|
// Checkpoint happens here
|
|
|
|
|
|
|
|
waitBarrier(this.finishRestore); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void beforeCheckpoint(org.crac.Context<? extends org.crac.Resource> context) { |
|
|
|
public void beforeCheckpoint(org.crac.Context<? extends org.crac.Resource> context) { |
|
|
|
// A non-daemon thread for preventing an accidental JVM shutdown before the checkpoint
|
|
|
|
Thread thread = new Thread(this::preventShutdown, "prevent-shutdown"); |
|
|
|
this.barrier = new CyclicBarrier(2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Thread thread = new Thread(() -> { |
|
|
|
|
|
|
|
awaitPreventShutdownBarrier(); |
|
|
|
|
|
|
|
// Checkpoint happens here
|
|
|
|
|
|
|
|
awaitPreventShutdownBarrier(); |
|
|
|
|
|
|
|
}, "prevent-shutdown"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
thread.setDaemon(false); |
|
|
|
thread.setDaemon(false); |
|
|
|
thread.start(); |
|
|
|
thread.start(); |
|
|
|
awaitPreventShutdownBarrier(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug("Stopping Spring-managed lifecycle beans before JVM checkpoint"); |
|
|
|
logger.debug("Stopping Spring-managed lifecycle beans before JVM checkpoint"); |
|
|
|
stopForRestart(); |
|
|
|
stopForRestart(); |
|
|
|
@ -737,11 +735,24 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void afterRestore(org.crac.Context<? extends org.crac.Resource> context) { |
|
|
|
public void afterRestore(org.crac.Context<? extends org.crac.Resource> context) { |
|
|
|
|
|
|
|
// Unlock barrier for beforeCheckpoint
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
this.stepToRestore.await(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
logger.trace("Exception from stepToRestore barrier", ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
logger.info("Restarting Spring-managed lifecycle beans after JVM restore"); |
|
|
|
logger.info("Restarting Spring-managed lifecycle beans after JVM restore"); |
|
|
|
restartAfterStop(); |
|
|
|
restartAfterStop(); |
|
|
|
|
|
|
|
|
|
|
|
// Barrier for prevent-shutdown thread not needed anymore
|
|
|
|
// Unlock barrier for afterRestore to shutdown "prevent-shutdown" thread
|
|
|
|
this.barrier = null; |
|
|
|
try { |
|
|
|
|
|
|
|
this.finishRestore.await(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
logger.trace("Exception from stepToRestore barrier", ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!checkpointOnRefresh) { |
|
|
|
if (!checkpointOnRefresh) { |
|
|
|
logger.info("Spring-managed lifecycle restart completed (restored JVM running for " + |
|
|
|
logger.info("Spring-managed lifecycle restart completed (restored JVM running for " + |
|
|
|
@ -749,11 +760,9 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void awaitPreventShutdownBarrier() { |
|
|
|
private void waitBarrier(CyclicBarrier barrier) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
if (this.barrier != null) { |
|
|
|
barrier.await(); |
|
|
|
this.barrier.await(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) { |
|
|
|
catch (Exception ex) { |
|
|
|
logger.trace("Exception from prevent-shutdown barrier", ex); |
|
|
|
logger.trace("Exception from prevent-shutdown barrier", ex); |
|
|
|
|