Skip to content

Commit

Permalink
Introduce isClosed() in NamespacedHierarchicalStore
Browse files Browse the repository at this point in the history
Closes #3807
  • Loading branch information
sbrannen committed May 6, 2024
1 parent 63ce7b9 commit 0ce27d2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
Expand Up @@ -84,6 +84,18 @@ public NamespacedHierarchicalStore<N> newChild() {
return new NamespacedHierarchicalStore<>(this, this.closeAction);
}

/**
* Determine if this store has been {@linkplain #close() closed}.
*
* @return {@code true} if this store has been closed
* @since 1.11
* @see #close()
*/
@API(status = EXPERIMENTAL, since = "1.11")
public boolean isClosed() {
return this.closed;
}

/**
* If a close action is configured, it will be called with all successfully
* stored values in reverse insertion order.
Expand All @@ -92,6 +104,8 @@ public NamespacedHierarchicalStore<N> newChild() {
*
* <p>Invocations of this method after the store has already been closed will
* be ignored.
*
* @see #isClosed()
*/
@Override
public void close() {
Expand Down
Expand Up @@ -28,6 +28,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -371,6 +372,11 @@ void additionNamespacePartMakesADifference() {
@Nested
class CloseActionTests {

@BeforeEach
void prerequisites() {
assertNotClosed();
}

@Test
void callsCloseActionInReverseInsertionOrderWhenClosingStore() throws Throwable {
store.put(namespace, "key1", "value1");
Expand All @@ -379,6 +385,8 @@ void callsCloseActionInReverseInsertionOrderWhenClosingStore() throws Throwable
verifyNoInteractions(closeAction);

store.close();
assertClosed();

var inOrder = inOrder(closeAction);
inOrder.verify(closeAction).close(namespace, "key3", "value3");
inOrder.verify(closeAction).close(namespace, "key2", "value2");
Expand All @@ -391,6 +399,7 @@ void doesNotCallCloseActionForRemovedValues() {
store.remove(namespace, key);

store.close();
assertClosed();

verifyNoInteractions(closeAction);
}
Expand All @@ -401,6 +410,7 @@ void doesNotCallCloseActionForReplacedValues() throws Throwable {
store.put(namespace, key, "value2");

store.close();
assertClosed();

verify(closeAction).close(namespace, key, "value2");
verifyNoMoreInteractions(closeAction);
Expand All @@ -411,6 +421,7 @@ void doesNotCallCloseActionForNullValues() {
store.put(namespace, key, null);

store.close();
assertClosed();

verifyNoInteractions(closeAction);
}
Expand All @@ -422,6 +433,7 @@ void ignoresStoredValuesThatThrewExceptionsDuringCleanup() {
}));

assertDoesNotThrow(store::close);
assertClosed();

verifyNoInteractions(closeAction);
}
Expand All @@ -433,6 +445,8 @@ void doesNotIgnoreStoredValuesThatThrewUnrecoverableFailuresDuringCleanup() {
}));

assertThrows(OutOfMemoryError.class, store::close);
// TODO Reinstate assertion once we ensure the store is closed even if an exception is thrown.
// assertClosed();

verifyNoInteractions(closeAction);
}
Expand All @@ -444,17 +458,20 @@ void closeIsIdempotent() throws Throwable {
verifyNoInteractions(closeAction);

store.close();
assertClosed();

verify(closeAction, times(1)).close(namespace, "key1", "value1");

store.close();
assertClosed();

verifyNoMoreInteractions(closeAction);
}

@Test
void rejectsModificationAfterClose() {
store.close();
assertClosed();

assertThrows(IllegalStateException.class, () -> store.put(namespace, "key1", "value1"));
assertThrows(IllegalStateException.class, () -> store.remove(namespace, "key1"));
Expand All @@ -464,6 +481,7 @@ void rejectsModificationAfterClose() {
@Test
void rejectsQueryAfterClose() {
store.close();
assertClosed();

assertThrows(IllegalStateException.class, () -> store.get(namespace, "key1"));
assertThrows(IllegalStateException.class, () -> store.get(namespace, "key1", Integer.class));
Expand All @@ -472,6 +490,15 @@ void rejectsQueryAfterClose() {
assertThrows(IllegalStateException.class,
() -> store.getOrComputeIfAbsent(namespace, "key1", k -> 1337, Integer.class));
}

private void assertNotClosed() {
assertThat(store.isClosed()).as("closed").isFalse();
}

private void assertClosed() {
assertThat(store.isClosed()).as("closed").isTrue();
}

}

private static Object createObject(String display) {
Expand Down

0 comments on commit 0ce27d2

Please sign in to comment.