Skip to content

Commit

Permalink
Add method to get a null value if provider does not hold a value anymore
Browse files Browse the repository at this point in the history
  • Loading branch information
OptimumCode committed Oct 23, 2023
1 parent a43fc45 commit f1e7eb3
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

import static com.exactpro.cradle.CradleStorage.DEFAULT_MAX_MESSAGE_BATCH_SIZE;
import static com.exactpro.cradle.CradleStorage.DEFAULT_MAX_TEST_EVENT_BATCH_SIZE;
Expand Down Expand Up @@ -186,6 +185,8 @@ public AbstractCommonFactory(FactorySettings settings) {
public void start() {
DefaultExports.initialize();

// init exporter
prometheusExporter.getOrNull();
livenessMonitor.enable();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,32 @@ internal class LazyProvider<T : Any?> private constructor(
}

fun get(): T {
return getState().value
}

/**
* The difference from [get] method is that this one does not throw an exception
* if provider already closed.
* However, it will still throw an exception if value initialization is failed
*/
fun getOrNull(): T? {
return getState().takeIf { it is State.Hold }?.value
}

private fun getState(): State<T> {
return if (reference.compareAndSet(null, State.Init)) {
val holder = State.Hold(initialize())
if (!reference.compareAndSet(State.Init, holder)) {
onClose.consume(holder.value)
error("provider '$name' already closed")
}
holder.value
holder
} else {
var currentState: State<T>?
do {
currentState = reference.get()
} while (currentState == State.Init || currentState == null)
currentState.value
currentState
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@

package com.exactpro.th2.common.schema.factory

import com.exactpro.th2.common.schema.exception.CommonFactoryException
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.RepeatedTest
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.inOrder
import org.mockito.kotlin.mock
Expand All @@ -29,6 +34,8 @@ import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
import java.util.concurrent.ForkJoinPool
import java.util.concurrent.ThreadLocalRandom
import kotlin.test.assertContains
import kotlin.test.assertNotNull

internal class LazyProviderTest {
@RepeatedTest(50)
Expand Down Expand Up @@ -132,4 +139,22 @@ internal class LazyProviderTest {
"unexpected errors thrown: $errors"
}
}

@Test
fun `null resources`() {
val provider = LazyProvider.lazy<Int?>("test") { null }
Assertions.assertEquals(null, provider.get(), "unexpected value")
}

@ParameterizedTest
@ValueSource(booleans = [true, false])
fun `exception in supplier`(safeCall: Boolean) {
val provider = LazyProvider.lazy<Unit>("test") { error("supplier error") }
val ex = assertThrows<CommonFactoryException> {
if (safeCall) provider.getOrNull() else provider.get()
}
assertNotNull(ex.cause?.message, "no cause") {
assertContains(it, "supplier error")
}
}
}

0 comments on commit f1e7eb3

Please sign in to comment.