|
34 | 34 |
|
35 | 35 | import org.apache.commons.logging.Log;
|
36 | 36 | import org.apache.commons.logging.LogFactory;
|
| 37 | +import org.crac.CheckpointException; |
| 38 | +import org.crac.Core; |
| 39 | +import org.crac.RestoreException; |
37 | 40 |
|
38 | 41 | import org.springframework.beans.factory.BeanFactory;
|
39 | 42 | import org.springframework.beans.factory.BeanFactoryAware;
|
|
45 | 48 | import org.springframework.context.Phased;
|
46 | 49 | import org.springframework.context.SmartLifecycle;
|
47 | 50 | import org.springframework.core.NativeDetector;
|
| 51 | +import org.springframework.core.SpringProperties; |
48 | 52 | import org.springframework.lang.Nullable;
|
49 | 53 | import org.springframework.util.Assert;
|
50 | 54 | import org.springframework.util.ClassUtils;
|
|
63 | 67 | */
|
64 | 68 | public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
|
65 | 69 |
|
| 70 | + /** |
| 71 | + * Property name for checkpoint restore: "spring.checkpoint.restore". |
| 72 | + * @since 6.1 |
| 73 | + * @see #CHECKPOINT_RESTORE_ON_REFRESH |
| 74 | + * @see org.crac.Core#checkpointRestore() |
| 75 | + */ |
| 76 | + public static final String CHECKPOINT_RESTORE_PROPERTY_NAME = "spring.checkpoint.restore"; |
| 77 | + |
| 78 | + /** |
| 79 | + * Recognized value for checkpoint restore property: "onRefresh". |
| 80 | + * @since 6.1 |
| 81 | + * @see #CHECKPOINT_RESTORE_PROPERTY_NAME |
| 82 | + * @see org.crac.Core#checkpointRestore() |
| 83 | + */ |
| 84 | + public static final String CHECKPOINT_RESTORE_ON_REFRESH = "onRefresh"; |
| 85 | + |
| 86 | + |
| 87 | + private final static boolean checkpointRestoreOnRefresh = CHECKPOINT_RESTORE_ON_REFRESH.equalsIgnoreCase( |
| 88 | + SpringProperties.getProperty(CHECKPOINT_RESTORE_PROPERTY_NAME)); |
| 89 | + |
66 | 90 | private final Log logger = LogFactory.getLog(getClass());
|
67 | 91 |
|
68 | 92 | private volatile long timeoutPerShutdownPhase = 30000;
|
@@ -145,6 +169,10 @@ public void stop() {
|
145 | 169 |
|
146 | 170 | @Override
|
147 | 171 | public void onRefresh() {
|
| 172 | + if (checkpointRestoreOnRefresh) { |
| 173 | + new CracDelegate().checkpointRestore(); |
| 174 | + } |
| 175 | + |
148 | 176 | this.stoppedBeans = null;
|
149 | 177 | startBeans(true);
|
150 | 178 | this.running = true;
|
@@ -462,6 +490,22 @@ public Object registerResource() {
|
462 | 490 | org.crac.Core.getGlobalContext().register(resourceAdapter);
|
463 | 491 | return resourceAdapter;
|
464 | 492 | }
|
| 493 | + |
| 494 | + public void checkpointRestore() { |
| 495 | + logger.info("Triggering JVM checkpoint/restore"); |
| 496 | + try { |
| 497 | + Core.checkpointRestore(); |
| 498 | + } |
| 499 | + catch (UnsupportedOperationException ex) { |
| 500 | + throw new ApplicationContextException("CRaC checkpoint not supported on current JVM", ex); |
| 501 | + } |
| 502 | + catch (CheckpointException ex) { |
| 503 | + throw new ApplicationContextException("Failed to take CRaC checkpoint on refresh", ex); |
| 504 | + } |
| 505 | + catch (RestoreException ex) { |
| 506 | + throw new ApplicationContextException("Failed to restore CRaC checkpoint on refresh", ex); |
| 507 | + } |
| 508 | + } |
465 | 509 | }
|
466 | 510 |
|
467 | 511 |
|
|
0 commit comments