Skip to content

Commit

Permalink
Fix skipCloseOnExitHook setting not persisted.
Browse files Browse the repository at this point in the history
Closes #213
  • Loading branch information
yevgenp committed Jun 18, 2024
1 parent e36023e commit 7781611
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/CM_Tutorial.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ There are three pairs of serialization interfaces. Only one of them should be ch
section for some non-trivial example of implementing these methods. See also https://github.com/OpenHFT/Chronicle-Wire#using-wire[Wire tutorial].

9. Don't forget to initialize transient/cache/state fields of the instance in the end of
`readMarshallable()` implementation. This is needed, because fefore calling `readMarshallable()`,
`readMarshallable()` implementation. This is needed, because before calling `readMarshallable()`,
Wire framework creates a serializer instance by means of `Unsafe.allocateInstance()` rather than
calling any constructor.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package net.openhft.chronicle.hash.impl;

import java.nio.file.Files;
import net.openhft.chronicle.algo.locks.*;
import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.bytes.BytesStore;
Expand Down Expand Up @@ -56,6 +55,7 @@
import java.nio.channels.FileLock;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -99,7 +99,7 @@ public abstract class VanillaChronicleHash<K,
private static final long GLOBAL_MUTABLE_STATE_LOCK_OFFSET = 0L;
private static final long GLOBAL_MUTABLE_STATE_VALUE_OFFSET = 8L;
private final Runnable preShutdownAction;
private final boolean skipCloseOnExitHook;
private boolean skipCloseOnExitHook;
/////////////////////////////////////////////////
// If the hash was created in the first place, or read from disk
public transient boolean createdOrInMemory;
Expand Down Expand Up @@ -300,6 +300,7 @@ protected void readMarshallableFields(@NotNull final WireIn wireIn) {
tierBulkInnerOffsetToTiers = wireIn.read("tierBulkInnerOffsetToTiers").int64();
tiersInBulk = wireIn.read("tiersInBulk").int64();
log2TiersInBulk = wireIn.read("log2TiersInBulk").int32();
skipCloseOnExitHook = wireIn.read("skipCloseOnExitHook").bool();
}

@Override
Expand Down Expand Up @@ -345,6 +346,7 @@ public void writeMarshallable(@NotNull final WireOut wireOut) {
wireOut.write("tierBulkInnerOffsetToTiers").int64(tierBulkInnerOffsetToTiers);
wireOut.write("tiersInBulk").int64(tiersInBulk);
wireOut.write("log2TiersInBulk").int32(log2TiersInBulk);
wireOut.write("skipCloseOnExitHook").bool(skipCloseOnExitHook);
}

protected VanillaGlobalMutableState createGlobalMutableState() {
Expand Down
33 changes: 33 additions & 0 deletions src/test/java/net/openhft/chronicle/map/ExitHookTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@
import com.google.common.base.Preconditions;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.hash.impl.VanillaChronicleHash;
import net.openhft.chronicle.testframework.process.JavaProcessBuilder;
import org.jetbrains.annotations.NotNull;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicReference;
Expand Down Expand Up @@ -176,6 +179,36 @@ public void testSkipExitHook() throws IOException, InterruptedException {
waitForShutdownConfirmation(shutdownActionConfirmationFile, USER_SHUTDOWN_HOOK_EXECUTED, process);
}

@Test
public void testSerialization1() throws Exception {
File mapFile = folder.newFile();
ChronicleMap<Integer, Integer> expected = createMapBuilder()
.skipCloseOnExitHook(true)
.createPersistedTo(mapFile);
ChronicleMap<Integer, Integer> actual = createMapBuilder()
.createPersistedTo(mapFile);
Field skipCloseOnExitHook = getPrivateField(VanillaChronicleHash.class, "skipCloseOnExitHook");
assertEquals(skipCloseOnExitHook.get(expected), skipCloseOnExitHook.get(actual));
}

@Test
public void testSerialization2() throws Exception {
File mapFile = folder.newFile();
ChronicleMap<Integer, Integer> expected = createMapBuilder()
.createPersistedTo(mapFile);
expected.close();
ChronicleMap<Integer, Integer> actual = createMapBuilder()
.createPersistedTo(mapFile);
Field skipCloseOnExitHook = getPrivateField(VanillaChronicleHash.class, "skipCloseOnExitHook");
assertEquals(false, skipCloseOnExitHook.get(actual));
}

private static @NotNull Field getPrivateField(Class<?> aClass, String fieldName) throws NoSuchFieldException {
Field field = aClass.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
}

private void waitForLockingConfirmation(File lockingConfirmationFile) throws IOException {
long started = System.currentTimeMillis();
do {
Expand Down

0 comments on commit 7781611

Please sign in to comment.