Skip to content

Commit

Permalink
Add io.openliberty.before.checkpoint condition
Browse files Browse the repository at this point in the history
This condition gets registered by the kernel when
a checkpoint has been requested and is unregistered
just before entering single-threaded mode in the JVM
to prepare for the checkpoint.
  • Loading branch information
tjwatson committed Sep 21, 2024
1 parent aacf482 commit 6aff88c
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ public enum CheckpointPhase {
*/
public static final String CONDITION_PROCESS_RUNNING_ID = "io.openliberty.process.running";

/**
* The ID of the condition service that indicates the Liberty process will have a checkpoint done
* in the future. This condition will be unregistered just before the JVM goes into single-thread
* mode to prepare for the checkpoint.
*/
public static final String CONDITION_BEFORE_CHECKPOINT_ID = "io.openliberty.before.checkpoint";

private static final String SERVICE_RANKING = "service.ranking";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,12 @@ public void restore() {

}, FrameworkUtil.asDictionary(Collections.singletonMap(Constants.SERVICE_RANKING, Integer.MIN_VALUE)));

final ServiceRegistration<Condition> beforeCheckpointReg = //
fwkContext.registerService(Condition.class,
Condition.INSTANCE,
FrameworkUtil.asDictionary(Collections.singletonMap(Condition.CONDITION_ID,
CheckpointPhase.CONDITION_BEFORE_CHECKPOINT_ID)));

Hashtable<String, Object> restoredHookProps = new Hashtable<>();
restoredHookProps.put(Constants.SERVICE_RANKING, Integer.MIN_VALUE);
restoredHookProps.put(CheckpointHook.MULTI_THREADED_HOOK, Boolean.TRUE);
Expand All @@ -663,6 +669,7 @@ public void restore() {
public void prepare() {
// kick equinox to force a save before checkpoint single-threaded mode
saveEquinoxStateNow(fwkContext);
beforeCheckpointReg.unregister();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ public void testAddImmutableEnvKey() throws Exception {
public void testRunningConditionLaunch() throws Exception {
server.startServer(getTestMethodNameOnly(testName) + ".log");
findLogMessage("Activate should have non-null running condition", "TESTING - activate running condition: ", "io.openliberty.process.running null", 500);
findLogMessage("Activate should have null before checkpoint condition", "TESTING - activate before checkpoint condition: ", "null", 500);
}

@Test
public void testBeforeCheckpointAndRunningCondition() throws Exception {
// The before checkpoint condition is tested in the lambda setup in setCheckpoint
server.startServer(getTestMethodNameOnly(testName) + ".log");
findLogMessage("Should bind running condition on restore", "TESTING - bind running condition:", " io.openliberty.process.running AFTER_APP_START", 500);
}

@Test
Expand Down Expand Up @@ -152,6 +160,8 @@ private void setCheckpoint(TestMethod testMethod) {
findLogMessage("No RESTORED false found in prepare", "TESTING - in prepare method RESTORED", " - false -- false", 500);
findLogMessage("Activate should have null running condition", "TESTING - activate running condition: ", "null", 500);
findLogMessage("Prepare should have null running condition", "TESTING - prepare running condition: ", "null", 500);
findLogMessage("Should activate the before checkpoint component", "TESTING - activate before checkpoint condition component", "", 500);
findLogMessage("Should deactivate the before checkpoint component", "TESTING - deactivate before checkpoint condition component", "", 500);
runBeforeRestore(testMethod);
}));
}
Expand Down Expand Up @@ -193,6 +203,7 @@ static enum TestMethod {
testRunningConditionLaunch,
testFailedCheckpoint,
testFailedRestore,
testBeforeCheckpointAndRunningCondition,
unknown
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2024 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/

package test.checkpoint.config.bundle;

import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.propertytypes.SatisfyingConditionTarget;
import org.osgi.service.condition.Condition;

import io.openliberty.checkpoint.spi.CheckpointPhase;

/**
*
*/
@Component
@SatisfyingConditionTarget("(" + Condition.CONDITION_ID + "=" + CheckpointPhase.CONDITION_BEFORE_CHECKPOINT_ID + ")")
public class TestBeforeCheckpointComponent {
@Activate
public TestBeforeCheckpointComponent(ComponentContext cc) {
System.out.println("TESTING - activate before checkpoint condition component");
}

@Deactivate
public void deactivate() {
System.out.println("TESTING - deactivate before checkpoint condition component");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class TestCheckpointHook implements CheckpointHook {
private final CheckpointPhase phase;
private final ServiceReference<CheckpointPhase> phaseRef;
private volatile ServiceReference<Condition> runningCondition = null;
private volatile ServiceReference<Condition> beforeCheckpointCondition = null;

@Activate
public TestCheckpointHook(Map<String, Object> config,
Expand All @@ -58,6 +59,7 @@ public TestCheckpointHook(Map<String, Object> config,
@Activate
void activate() {
System.out.println("TESTING - activate running condition: " + getRunningCondition());
System.out.println("TESTING - activate before checkpoint condition: " + getBeforeCheckpointCondition());
}

@Reference(service = Condition.class, //
Expand All @@ -73,6 +75,19 @@ protected void unsetRunningCondition(ServiceReference<Condition> runningConditio
this.runningCondition = null;
}

@Reference(service = Condition.class, //
policy = ReferencePolicy.DYNAMIC, //
cardinality = ReferenceCardinality.OPTIONAL, //
target = "(" + Condition.CONDITION_ID + "=" + CheckpointPhase.CONDITION_BEFORE_CHECKPOINT_ID + ")")
protected void setBeforeCheckpointCondition(ServiceReference<Condition> beforeCheckpointCondition) {
this.beforeCheckpointCondition = beforeCheckpointCondition;
System.out.println("TESTING - bind before checkpoint condition: " + getBeforeCheckpointCondition());
}

protected void unsetBeforeCheckpointCondition(ServiceReference<Condition> runningCondition) {
this.beforeCheckpointCondition = null;
}

/**
* @return
*/
Expand All @@ -84,6 +99,14 @@ private String getRunningCondition() {
}
}

private String getBeforeCheckpointCondition() {
if (beforeCheckpointCondition == null) {
return "null";
} else {
return (String) beforeCheckpointCondition.getProperty(Condition.CONDITION_ID);
}
}

@Modified
public void modifiedConfig(Map<String, Object> modified) {
config.putAll(modified);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#*******************************************************************************
# Copyright (c) 2019, 2023 IBM Corporation and others.
# Copyright (c) 2019, 2024 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
# which accompanies this distribution, and is available at
Expand All @@ -24,7 +24,8 @@ Private-Package: \

-dsannotations: \
test.checkpoint.config.bundle.TestCheckpointHook, \
test.checkpoint.config.bundle.TestStaticHookRegister
test.checkpoint.config.bundle.TestStaticHookRegister, \
test.checkpoint.config.bundle.TestBeforeCheckpointComponent

IBM-Default-Config: OSGI-INF/wlp/defaultInstances.xml

Expand Down

0 comments on commit 6aff88c

Please sign in to comment.