diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Builder.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Builder.kt deleted file mode 100644 index ed7a852..0000000 --- a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Builder.kt +++ /dev/null @@ -1,97 +0,0 @@ -package com.sksamuel.aedile.core - -import com.github.benmanes.caffeine.cache.AsyncCacheLoader -import com.github.benmanes.caffeine.cache.Caffeine -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.async -import kotlinx.coroutines.future.asCompletableFuture -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Executor - -@Deprecated("Use extension functions on caffeine instead", ReplaceWith("Caffeine.newBuilder()")) -class Builder( - private val defaultScope: CoroutineScope, - private val useCallingContext: Boolean, - private val caffeine: Caffeine, -) { - - /** - * Returns a [Cache] which suspends when requesting values. - * - * If the key is not present in the cache, returns null, unless a compute function - * is provided with the key. - * - * If the suspendable computation throws or computes a null value then the - * entry will be automatically removed. - */ - fun build(): Cache { - return Cache(defaultScope, useCallingContext, caffeine.buildAsync()) - } - - /** - * Returns a [Cache] which suspends when requesting values. - * - * If the key does not exist, then the suspendable [compute] function is invoked - * to compute a value, unless a specific compute has been provided with the key. - * - * If the suspendable computation throws or computes a null value then the - * entry will be automatically removed. - * - */ - fun build(compute: suspend (K) -> V): LoadingCache { - return LoadingCache( - defaultScope, - useCallingContext, - caffeine.buildAsync { key, _ -> defaultScope.async { compute(key) }.asCompletableFuture() } - ) - } - - /** - * Returns a [Cache] which suspends when requesting values. - * - * If the key does not exist, then the suspendable [compute] function is invoked - * to compute a value, unless a specific compute has been provided with the key. - * - * If the suspendable computation throws or computes a null value then the - * entry will be automatically removed. - * - * The [reloadCompute] function is invoked to refresh an entry if refreshAfterWrite - * is enabled or refresh is invoked. See full docs [AsyncCacheLoader.asyncReload]. - * - */ - fun build(compute: suspend (K) -> V, reloadCompute: suspend (K, V) -> V): LoadingCache { - return LoadingCache( - defaultScope, - useCallingContext, - caffeine.buildAsync(object : AsyncCacheLoader { - override fun asyncLoad(key: K, executor: Executor?): CompletableFuture { - return defaultScope.async { compute(key) }.asCompletableFuture() - } - - override fun asyncReload(key: K, oldValue: V, executor: Executor?): CompletableFuture { - return defaultScope.async { reloadCompute(key, oldValue) }.asCompletableFuture() - } - }) - ) - } - - /** - * Returns a [Cache] which suspends when requesting values. - * - * If a requested key does not exist, then the suspendable [compute] function is invoked - * to compute the required values. - * - * If the suspendable computation throws or computes a null value then the - * entry will be automatically removed. - * - */ - fun buildAll(compute: suspend (Set) -> Map): LoadingCache { - return LoadingCache( - defaultScope, - useCallingContext, - caffeine.buildAsync(AsyncCacheLoader.bulk { keys, _ -> - defaultScope.async { compute(keys) }.asCompletableFuture() - }) - ) - } -} diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Cache.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Cache.kt index a5b53fa..9dcd949 100644 --- a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Cache.kt +++ b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Cache.kt @@ -11,9 +11,7 @@ import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import kotlin.coroutines.coroutineContext -class Cache( - @Deprecated("This should be ignored - use overloaded methods") private val defaultScope: CoroutineScope, - @Deprecated("This should be ignored - use overloaded methods") private val useCallingContext: Boolean, +class Cache( private val cache: AsyncCache ) { @@ -24,7 +22,7 @@ class Cache( } /** - * Returns the value associated with key in this cache, or null if there is no cached future for key. + * Returns the value associated with a key in this cache, or null if there is no cached future for the key. * This method will suspend while the value is fetched. * For a non-suspending alternative, see [getOrNull]. */ @@ -33,7 +31,7 @@ class Cache( } /** - * Returns the value associated with key in this cache or null if this cache does not + * Returns the value associated with a key in this cache or null if this cache does not * contain an entry for the key. This is a non-suspendable alternative to getIfPresent(key). */ fun getOrNull(key: K): V? { @@ -41,7 +39,7 @@ class Cache( } /** - * Returns the value associated with key in this cache, obtaining that value from the + * Returns the value associated with a key in this cache, getting that value from the * [compute] function if necessary. This function will suspend while the compute method * is executed. * @@ -55,10 +53,10 @@ class Cache( * */ suspend fun get(key: K, compute: suspend (K) -> V): V { - val scope = scope() + val scope = CoroutineScope(coroutineContext) var error: Throwable? = null val value = cache.get(key) { k, _ -> - scope.async { + val asCompletableFuture = scope.async { // if compute throws, then it will cause the parent coroutine to be cancelled as well // we don't want that, as want to throw the exception back to the caller. // so we must capture it and throw it manually @@ -69,25 +67,28 @@ class Cache( null } }.asCompletableFuture() + asCompletableFuture.thenApply { it ?: throw error ?: NullPointerException() } }.await() error?.let { throw it } return value } /** - * Returns the value associated with key in this cache, obtaining that value from the + * Returns the value associated with a key in this cache, getting that value from the * [compute] function if necessary. This function will suspend while the compute method * is executed. If the suspendable computation throws, the exception will be propagated to the caller. * * If the specified key is not already associated with a value, attempts to compute its value asynchronously - * and enters it into this cache unless null. + * and enters it into this cache unless null. The entire method invocation is performed atomically, so the + * function is applied at most once per key. If the asynchronous computation fails, the entry will be + * automatically removed from this cache. * * @param key the key to lookup in the cache * @param compute the suspendable function to generate a value for the given key. * @return the present value, the computed value, or throws. */ suspend fun getOrNull(key: K, compute: suspend (K) -> V?): V? { - val scope = scope() + val scope = CoroutineScope(coroutineContext) return cache.get(key) { k, _ -> scope.async { compute(k) }.asCompletableFuture() }.await() } @@ -115,10 +116,10 @@ class Cache( * If the suspendable computation throws, the entry will be automatically removed. * * @param key the key to associate the computed value with - * @param compute the suspendable function that generate the value. + * @param compute the suspendable function that generates the value. */ suspend fun put(key: K, compute: suspend () -> V) { - val scope = scope() + val scope = CoroutineScope(coroutineContext) cache.put(key, scope.async { compute() }.asCompletableFuture()) } @@ -140,7 +141,7 @@ class Cache( } suspend fun getAll(keys: Collection, compute: suspend (Collection) -> Map): Map { - val scope = scope() + val scope = CoroutineScope(coroutineContext) var error: Throwable? = null val value = cache.getAll(keys) { ks: Set, _: Executor -> scope.async { @@ -176,8 +177,4 @@ class Cache( fun invalidateAll() { cache.synchronous().invalidateAll() } - - private suspend fun scope(): CoroutineScope { - return if (useCallingContext) CoroutineScope(coroutineContext) else defaultScope - } } diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/CacheBuilder.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/CacheBuilder.kt deleted file mode 100644 index 7f2bb4b..0000000 --- a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/CacheBuilder.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.sksamuel.aedile.core - -import com.github.benmanes.caffeine.cache.Caffeine -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.future.asCompletableFuture -import kotlinx.coroutines.launch -import kotlin.time.Duration.Companion.nanoseconds -import kotlin.time.toJavaDuration - -/** - * Creates a [Builder] which by default uses the coroutine context from the caller for get/getall compute overrides. - * To delegate to a global dispatcher, set the dispatcher in the configuration. - */ -@Deprecated("Use Caffeine.newBuilder directly and use extension functions for Kotlin behaviour. Eg, Caffeine.newBuilder().buildAsync()") -fun cacheBuilder(configure: Configuration.() -> Unit = {}): Builder { - - val c = Configuration() - c.configure() - val caffeine = Caffeine.newBuilder() - - val defaultScope = c.scope ?: CoroutineScope(c.dispatcher + CoroutineName("Aedile-Caffeine-Scope") + SupervisorJob()) - - c.evictionListener.let { listener -> - caffeine.evictionListener { key, value, cause -> - defaultScope.launch { - listener.invoke(key, value, cause) - } - } - } - - c.removalListener.let { listener -> - caffeine.removalListener { key, value, cause -> - defaultScope.launch { - listener.invoke(key, value, cause) - } - } - } - - c.initialCapacity?.let { caffeine.initialCapacity(it) } - c.ticker?.let { caffeine.ticker(it) } - - c.maximumSize?.let { caffeine.maximumSize(it) } - c.maximumWeight?.let { caffeine.maximumWeight(it) } - c.weigher?.let { caffeine.weigher(it) } - - c.expireAfterWrite?.let { caffeine.expireAfterWrite(it.toJavaDuration()) } - c.expireAfterAccess?.let { caffeine.expireAfterAccess(it.toJavaDuration()) } - c.expireAfter?.let { caffeine.expireAfter(it) } - - c.refreshAfterWrite?.let { caffeine.refreshAfterWrite(it.toJavaDuration()) } - c.statsCounter?.let { counter -> caffeine.recordStats { counter } } - - if (c.weakKeys == true) caffeine.weakKeys() - if (c.softValues == true) caffeine.softValues() - - c.scheduler?.let { scheduler -> - caffeine.scheduler { _, command, delay, unit -> - scheduler.schedule( - { command.run() }, - unit.toNanos(delay).nanoseconds, - ).asCompletableFuture() - } - } - - return Builder(defaultScope, c.useCallingContext, caffeine) -} diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/LoadingCache.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/LoadingCache.kt index 88bfbd3..8d814c1 100644 --- a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/LoadingCache.kt +++ b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/LoadingCache.kt @@ -11,7 +11,7 @@ import kotlinx.coroutines.future.await import java.util.concurrent.CompletableFuture import kotlin.coroutines.coroutineContext -class LoadingCache( +class LoadingCache( private val defaultScope: CoroutineScope, private val useCallingContext: Boolean, private val cache: AsyncLoadingCache @@ -73,9 +73,9 @@ class LoadingCache( } /** - * Returns the value associated with key in this cache, obtaining that value from the + * Returns the value associated with a key in this cache, getting that value from the * [compute] function if necessary. This method provides a simple substitute for the conventional - * "if cached, return; otherwise create, cache and return" pattern. + * "if cached, return; otherwise create, cache, and return" pattern. * * The instance returned from the compute function will be stored directly into the cache. * @@ -90,7 +90,7 @@ class LoadingCache( } /** - * Returns the value associated with key in this cache, obtaining that value from the + * Returns the value associated with a key in this cache, getting that value from the * [compute] function if necessary. This function will suspend while the compute method * is executed. If the suspendable computation throws, the exception will be propagated to the caller. * @@ -160,7 +160,7 @@ class LoadingCache( /** * Discards the given key in the cache. * Will block until completed. - * Behavior of the entry if currently being loaded is undefined. + * The behavior of the entry if currently being loaded is undefined. */ fun invalidate(key: K) { cache.synchronous().invalidate(key) @@ -169,14 +169,14 @@ class LoadingCache( /** * Discards all entries in the cache. * Will block until completed. - * Behavior of entries currently being loaded is undefined. + * The behavior of entries currently being loaded is undefined. */ fun invalidateAll() { cache.synchronous().invalidateAll() } /** - * Loads a new value for the key, asynchronously. While the new value is loading the + * Loads a new value for the key, asynchronously. While the new value is loading, the * previous value (if any) will continue to be returned by get(key) unless it is evicted. * * See full docs at [com.github.benmanes.caffeine.cache.LoadingCache.refresh]. @@ -186,12 +186,12 @@ class LoadingCache( } /** - * Loads a new value for each key, asynchronously. While the new value is loading the + * Loads a new value for each key, asynchronously. While the new value is loading, the * previous value (if any) will continue to be returned by get(key) unless it is evicted. * * See full docs at [com.github.benmanes.caffeine.cache.LoadingCache.refreshAll]. */ - suspend fun refreshAll(keys: Collection): Map { + suspend fun refreshAll(keys: Collection): Map { return cache.synchronous().refreshAll(keys).await() } diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Scheduler.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Scheduler.kt new file mode 100644 index 0000000..baa2303 --- /dev/null +++ b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/Scheduler.kt @@ -0,0 +1,10 @@ +package com.sksamuel.aedile.core + +import kotlinx.coroutines.Deferred +import kotlin.time.Duration + +fun interface Scheduler { + fun schedule(command: () -> Unit, duration: Duration): Deferred +} + + diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/builders.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/builders.kt index ffb0df1..1816ab6 100644 --- a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/builders.kt +++ b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/builders.kt @@ -17,10 +17,10 @@ import java.util.concurrent.Executor * If the key is not present in the cache, returns null, unless a compute function * is provided with the key. * - * If the suspendable computation throws or computes a null value then the + * If the suspendable computation throws or computes a null value, then the * entry will be automatically removed. */ -fun Caffeine.asCache(): Cache { +fun Caffeine.asCache(): Cache { val scope = CoroutineScope(Dispatchers.IO + CoroutineName("Aedile-AsyncLoadingCache-Scope") + SupervisorJob()) return asCache(scope) } @@ -28,24 +28,24 @@ fun Caffeine.asCache(): Cache { /** * Returns a [Cache] which suspends when requesting values. * - * If the key is not present in the cache, returns null, unless a compute function + * If the key is not present in the cache, it returns null, unless a compute function * is provided with the key. * - * If the suspendable computation throws or computes a null value then the + * If the suspendable computation throws or computes a null value, then the * entry will be automatically removed. */ -fun Caffeine.asCache(scope: CoroutineScope): Cache { - return Cache(scope, true, buildAsync()) +fun Caffeine.asCache(scope: CoroutineScope): Cache { + return Cache(buildAsync()) } /** * Returns a [LoadingCache] which uses the provided [compute] function * to compute a value, unless a specific compute has been provided with the key. * - * If the suspendable computation throws or computes a null value then the + * If the suspendable computation throws or computes a null value, then the * entry will be automatically removed. */ -fun Caffeine.asLoadingCache(compute: suspend (K) -> V): LoadingCache { +fun Caffeine.asLoadingCache(compute: suspend (K) -> V): LoadingCache { val scope = CoroutineScope(Dispatchers.IO + CoroutineName("Aedile-AsyncLoadingCache-Scope") + SupervisorJob()) return asLoadingCache(scope, compute) } @@ -59,7 +59,7 @@ fun Caffeine.asLoadingCache(compute: suspend (K * If the suspendable computation throws or computes a null value then the * entry will be automatically removed. */ -fun Caffeine.asLoadingCache( +fun Caffeine.asLoadingCache( scope: CoroutineScope, compute: suspend (K) -> V ): LoadingCache { @@ -72,13 +72,13 @@ fun Caffeine.asLoadingCache( * If the key does not exist, then the suspendable [compute] function is invoked * to compute a value, unless a specific compute has been provided with the key. * - * If the suspendable computation throws or computes a null value then the + * If the suspendable computation throws or computes a null value, then the * entry will be automatically removed. * * The [reloadCompute] function is invoked to refresh an entry if refreshAfterWrite * is enabled or refresh is invoked. See full docs [AsyncCacheLoader.asyncReload]. */ -fun Caffeine.asLoadingCache( +fun Caffeine.asLoadingCache( compute: suspend (K) -> V, reloadCompute: suspend (K, V) -> V, ): LoadingCache { @@ -100,17 +100,17 @@ fun Caffeine.asLoadingCache( * * The compute functions will execute on the given [scope]. */ -fun Caffeine.asLoadingCache( +fun Caffeine.asLoadingCache( scope: CoroutineScope, compute: suspend (K) -> V, reloadCompute: suspend (K, V) -> V, ): LoadingCache { return LoadingCache(scope, true, buildAsync(object : AsyncCacheLoader { - override fun asyncLoad(key: K, executor: Executor?): CompletableFuture { + override fun asyncLoad(key: K, executor: Executor): CompletableFuture { return scope.async { compute(key) }.asCompletableFuture() } - override fun asyncReload(key: K, oldValue: V, executor: Executor?): CompletableFuture { + override fun asyncReload(key: K, oldValue: V, executor: Executor): CompletableFuture { return scope.async { reloadCompute(key, oldValue) }.asCompletableFuture() } })) @@ -125,7 +125,7 @@ fun Caffeine.asLoadingCache( * If the suspendable computation throws or computes a null value then the * entry will be automatically removed. */ -fun Caffeine.asBulkLoadingCache(compute: suspend (Set) -> Map): LoadingCache { +fun Caffeine.asBulkLoadingCache(compute: suspend (Set) -> Map): LoadingCache { val scope = CoroutineScope(Dispatchers.IO + CoroutineName("Aedile-AsyncLoadingCache-Scope") + SupervisorJob()) return asBulkLoadingCache(scope, compute) } @@ -141,7 +141,7 @@ fun Caffeine.asBulkLoadingCache(compute: suspen * * The compute function will execute on the given [scope]. */ -fun Caffeine.asBulkLoadingCache( +fun Caffeine.asBulkLoadingCache( scope: CoroutineScope, compute: suspend (Set) -> Map ): LoadingCache { diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/caffeine.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/caffeine.kt deleted file mode 100644 index 294587e..0000000 --- a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/caffeine.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.sksamuel.aedile.core - -import com.github.benmanes.caffeine.cache.Caffeine -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.future.asCompletableFuture -import kotlinx.coroutines.launch -import kotlin.time.Duration -import kotlin.time.Duration.Companion.nanoseconds -import kotlin.time.toJavaDuration - -/** - * Creates a [Builder] which by default uses [Dispatchers.IO] to execute computation functions. - */ -@Deprecated("Use extension functions. This deprecated builder retains the previous behaviour.", ReplaceWith("Caffeine.newBuilder()")) -fun caffeineBuilder(configure: Configuration.() -> Unit = {}): Builder { - - val c = Configuration() - c.configure() - val caffeine = Caffeine.newBuilder() - - val scope = c.scope ?: CoroutineScope(c.dispatcher + CoroutineName("Aedile-Caffeine-Scope") + SupervisorJob()) - - c.evictionListener.let { listener -> - caffeine.evictionListener { key, value, cause -> - scope.launch { - listener.invoke(key, value, cause) - } - } - } - - c.removalListener.let { listener -> - caffeine.removalListener { key, value, cause -> - scope.launch { - listener.invoke(key, value, cause) - } - } - } - - c.initialCapacity?.let { caffeine.initialCapacity(it) } - c.ticker?.let { caffeine.ticker(it) } - - c.maximumSize?.let { caffeine.maximumSize(it) } - c.maximumWeight?.let { caffeine.maximumWeight(it) } - c.weigher?.let { caffeine.weigher(it) } - - c.expireAfterWrite?.let { caffeine.expireAfterWrite(it.toJavaDuration()) } - c.expireAfterAccess?.let { caffeine.expireAfterAccess(it.toJavaDuration()) } - c.expireAfter?.let { caffeine.expireAfter(it) } - - c.refreshAfterWrite?.let { caffeine.refreshAfterWrite(it.toJavaDuration()) } - c.statsCounter?.let { counter -> caffeine.recordStats { counter } } - - if (c.weakKeys == true) caffeine.weakKeys() - if (c.softValues == true) caffeine.softValues() - - c.scheduler?.let { scheduler -> - caffeine.scheduler { _, command, delay, unit -> - scheduler.schedule( - { command.run() }, - unit.toNanos(delay).nanoseconds, - ).asCompletableFuture() - } - } - - return Builder(scope, false, caffeine) -} - -fun interface Scheduler { - fun schedule(command: () -> Unit, duration: Duration): Deferred -} - - diff --git a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/config.kt b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/config.kt index e9c4990..533e0c5 100644 --- a/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/config.kt +++ b/aedile-core/src/main/kotlin/com/sksamuel/aedile/core/config.kt @@ -17,7 +17,7 @@ import kotlin.time.toJavaDuration * * See full docs at [Caffeine.scheduler]. */ -fun Caffeine.scheduler(scheduler: Scheduler): Caffeine { +fun Caffeine.scheduler(scheduler: Scheduler): Caffeine { return scheduler { _, command, delay, unit -> scheduler.schedule( { command.run() }, @@ -32,7 +32,7 @@ fun Caffeine.scheduler(scheduler: Scheduler): Caffeine { * * See full docs at [Caffeine.removalListener]. */ -fun Caffeine.withRemovalListener( +fun Caffeine.withRemovalListener( listener: suspend (K?, V?, RemovalCause) -> Unit, ): Caffeine { val scope = createScope("Aedile-RemovalListener-Scope") @@ -43,7 +43,7 @@ fun Caffeine.withRemovalListener( * Specifies a listener that is notified each time an entry is removed. * See full docs at [Caffeine.removalListener]. */ -fun Caffeine.withRemovalListener( +fun Caffeine.withRemovalListener( scope: CoroutineScope, listener: suspend (K?, V?, RemovalCause) -> Unit, ): Caffeine { @@ -60,7 +60,7 @@ fun Caffeine.withRemovalListener( * * See full docs at [Caffeine.evictionListener]. */ -fun Caffeine.withEvictionListener( +fun Caffeine.withEvictionListener( listener: suspend (K?, V?, RemovalCause) -> Unit, ): Caffeine { val scope = createScope("Aedile-EvictionListener-Scope") @@ -72,7 +72,7 @@ fun Caffeine.withEvictionListener( * * See full docs at [Caffeine.evictionListener]. */ -fun Caffeine.withEvictionListener( +fun Caffeine.withEvictionListener( scope: CoroutineScope, listener: suspend (K?, V?, RemovalCause) -> Unit, ): Caffeine { @@ -86,21 +86,21 @@ fun Caffeine.withEvictionListener( /** * See full docs at [Caffeine.refreshAfterWrite]. */ -fun Caffeine.refreshAfterWrite(duration: Duration): Caffeine { +fun Caffeine.refreshAfterWrite(duration: Duration): Caffeine { return this.refreshAfterWrite(duration.toJavaDuration()) } /** * See full docs at [Caffeine.expireAfterAccess]. */ -fun Caffeine.expireAfterAccess(duration: Duration): Caffeine { +fun Caffeine.expireAfterAccess(duration: Duration): Caffeine { return this.expireAfterAccess(duration.toJavaDuration()) } /** * See full docs at [Caffeine.expireAfterWrite]. */ -fun Caffeine.expireAfterWrite(duration: Duration): Caffeine { +fun Caffeine.expireAfterWrite(duration: Duration): Caffeine { return this.expireAfterWrite(duration.toJavaDuration()) } diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AedileBuilderTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AedileBuilderTest.kt deleted file mode 100644 index 43b7f34..0000000 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AedileBuilderTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.sksamuel.aedile.core - -import io.kotest.core.spec.style.FunSpec -import kotlin.time.Duration.Companion.seconds - -class AedileBuilderTest : FunSpec() { - init { - test("cache with configuration options") { - caffeineBuilder { - maximumWeight = 100 - weigher = { _, _ -> 1 } - expireAfterAccess = 10.seconds - }.build() - } - } -} diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsCacheTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsCacheTest.kt index 153affa..f9883dd 100644 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsCacheTest.kt +++ b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsCacheTest.kt @@ -2,10 +2,13 @@ package com.sksamuel.aedile.core import com.github.benmanes.caffeine.cache.Caffeine import com.github.benmanes.caffeine.cache.Expiry +import io.kotest.assertions.nondeterministic.eventually import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import kotlinx.coroutines.delay +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds class AsCacheTest : FunSpec() { init { @@ -138,5 +141,52 @@ class AsCacheTest : FunSpec() { .expireAfter(loggerExpiry) .asCache() } + + test("expireAfterAccess") { + val cache = Caffeine.newBuilder() + .expireAfterAccess(500.milliseconds) + .asCache() + cache.get("foo") { "bar" } shouldBe "bar" + cache.getIfPresent("foo") shouldBe "bar" + cache.contains("foo") shouldBe true + delay(2.seconds) + cache.contains("foo") shouldBe false + } + + test("expireAfterWrite") { + val cache = Caffeine.newBuilder() + .expireAfterWrite(500.milliseconds) + .asCache() + cache.get("foo") { "bar" } shouldBe "bar" + cache.contains("foo") shouldBe true + eventually(5.seconds) { + cache.contains("foo") shouldBe false + } + } + + test("Cache should support getOrNull") { + val cache = Caffeine.newBuilder().asCache() + cache.put("foo", "bar") + cache.getOrNull("foo") shouldBe "bar" + cache.getOrNull("baqwewqewqz") shouldBe null + } + + test("getOrNull with compute") { + val cache = Caffeine.newBuilder().asCache() + cache.getOrNull("foo") { "bar" } shouldBe "bar" + cache.getOrNull("foo") { "bar2" } shouldBe "bar" // already cached so compute ignored + } + + test("getOrNull with compute that returns null should return null") { + val cache = Caffeine.newBuilder().asCache() + cache.getOrNull("foo") { null } shouldBe null + } + + test("getOrNull with compute that throws should return previous value") { + val cache = Caffeine.newBuilder().asCache() + cache.getOrNull("foo") { "bar" } shouldBe "bar" + cache.getOrNull("foo") { error("kapow") } + cache.getOrNull("foo") shouldBe "bar" + } } } diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsLoadingCacheTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsLoadingCacheTest.kt index e11ae8e..6c5915e 100644 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsLoadingCacheTest.kt +++ b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/AsLoadingCacheTest.kt @@ -6,7 +6,6 @@ import io.kotest.assertions.nondeterministic.eventually import io.kotest.assertions.throwables.shouldNotThrowAny import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.shouldBe import kotlinx.coroutines.delay import kotlinx.coroutines.supervisorScope @@ -81,7 +80,6 @@ class AsLoadingCacheTest : FunSpec() { "bar" } shouldBe "bar" val key = "baz" - cache.getOrNull(key) { null }.shouldBeNull() cache.getOrNull(key) { "new value" }.shouldBe("new value") cache.getOrNull(key) { "new value 2" }.shouldBe("new value") cache.getOrNull(key) { null }.shouldBe("new value") @@ -235,9 +233,9 @@ class AsLoadingCacheTest : FunSpec() { ) } - test("should support refreshAfterWrite using refresh compute function") { + test("should support refreshAfterWrite using compute function") { val value = AtomicInteger(0) - val cache = Caffeine.newBuilder().refreshAfterWrite(25.milliseconds).build { + val cache = Caffeine.newBuilder().refreshAfterWrite(25.milliseconds).asLoadingCache { value.incrementAndGet() } cache.get("foo") @@ -255,6 +253,31 @@ class AsLoadingCacheTest : FunSpec() { value.get() shouldBe 3 } + test("should support refreshAfterWrite using recompute function") { + val value = AtomicInteger(0) + val cache = Caffeine.newBuilder().refreshAfterWrite(25.milliseconds).asLoadingCache( + compute = { value.incrementAndGet() }, + reloadCompute = { key, old -> + value.incrementAndGet() + value.incrementAndGet() + value.incrementAndGet() + } + ) + cache.get("foo") + cache.get("foo") + cache.get("foo") + cache.get("foo") + value.get() shouldBe 1 + delay(100) + cache.get("foo") + delay(100) + value.get() shouldBe 4 + delay(100) + cache.get("foo") + delay(100) + value.get() shouldBe 7 + } + test("should support asMap") { val cache = Caffeine.newBuilder().asLoadingCache { delay(1) @@ -310,6 +333,20 @@ class AsLoadingCacheTest : FunSpec() { cache.getIfPresent("wibble") shouldBe null } + test("Cache should support invalidateAll") { + val cache = Caffeine.newBuilder().asLoadingCache { + delay(1) + "bar" + } + cache.put("wibble", "a") + cache.put("wobble", "b") + cache.getIfPresent("wibble") shouldBe "a" + cache.getIfPresent("wobble") shouldBe "b" + cache.invalidateAll() + cache.getIfPresent("wibble") shouldBe null + cache.getIfPresent("wobble") shouldBe null + } + test("Cache should support contains") { val cache = Caffeine.newBuilder().asLoadingCache { delay(1) diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CacheTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CacheTest.kt deleted file mode 100644 index 8f4afd3..0000000 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CacheTest.kt +++ /dev/null @@ -1,125 +0,0 @@ -package com.sksamuel.aedile.core - -import io.kotest.assertions.throwables.shouldNotThrowAny -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.nulls.shouldBeNull -import io.kotest.matchers.shouldBe -import kotlinx.coroutines.delay -import kotlinx.coroutines.yield - -class CacheTest : FunSpec() { - init { - - test("Cache should return null for missing keys") { - val cache = caffeineBuilder().build() - cache.getIfPresent("else") shouldBe null - } - - test("Cache should support simple puts") { - val cache = caffeineBuilder().build() - cache.put("foo", "bar") - cache["baz"] = "waz" - cache.getIfPresent("foo") shouldBe "bar" - cache.getIfPresent("baz") shouldBe "waz" - } - - test("Cache should support getOrNull") { - val cache = caffeineBuilder().build() - cache.put("foo", "bar") - cache.getOrNull("foo") shouldBe "bar" - cache.getOrNull("baqwewqewqz") shouldBe null - } - - test("Cache.get should support suspendable compute function") { - val cache = caffeineBuilder().build() - cache.get("foo") { - delay(1) - "bar" - } shouldBe "bar" - } - - test("cache should propagate exceptions in the get compute function override") { - val cache = caffeineBuilder().build() - shouldThrow { - cache.get("foo") { - error("kapow") - } - } - } - - test("Cache should support getOrNull with compute") { - val cache = caffeineBuilder().build() - cache.getOrNull("foo") { - yield() - "bar" - } shouldBe "bar" - val key = "baz" - cache.getOrNull(key) { null }.shouldBeNull() - cache.getOrNull(key) { "new value" }.shouldBe("new value") - cache.getOrNull(key) { "new value 2" }.shouldBe("new value") - cache.getOrNull(key) { null }.shouldBe("new value") - shouldNotThrowAny { cache.getOrNull(key) { error("kapow") } } - shouldThrow { cache.getOrNull("not present") { error("kapow") } } - } - - test("cache should propagate exceptions in the getAll compute function override") { - val cache = caffeineBuilder().build() - shouldThrow { - cache.getAll(setOf("foo", "bar")) { - error("kapow") - } - } - } - - test("Cache should support getAll") { - val cache = caffeineBuilder().build() - cache.put("foo") { - delay(1) - "wobble" - } - cache.put("bar") { - delay(1) - "wibble" - } - cache.put("baz") { - delay(1) - "wubble" - } - cache.getAll(listOf("foo", "bar", "baz")) { - mapOf("baz" to "wubble") - } shouldBe mapOf("foo" to "wobble", "bar" to "wibble", "baz" to "wubble") - } - - test("Cache should support asMap") { - val cache = caffeineBuilder().build() - cache.put("wibble", "wobble") - cache["bubble"] = "bobble" - cache.asMap() shouldBe mapOf("wibble" to "wobble", "bubble" to "bobble") - } - - test("Cache should support asDeferredMap") { - val cache = caffeineBuilder().build() - cache.put("wibble", "wobble") - cache["bubble"] = "bobble" - val map = cache.asDeferredMap() - map["wibble"]?.await() shouldBe "wobble" - map["bubble"]?.await() shouldBe "bobble" - } - - test("Cache should support invalidate") { - val cache = caffeineBuilder().build() - cache.put("wibble", "wobble") - cache.getIfPresent("wibble") shouldBe "wobble" - cache.invalidate("wibble") - cache.getIfPresent("wibble") shouldBe null - } - - test("Cache should support contains") { - val cache = caffeineBuilder().build() - cache.put("wibble", "wobble") - cache.contains("wibble") shouldBe true - cache.contains("bubble") shouldBe false - } - } -} diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CoroutineContextTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CoroutineContextTest.kt index a4735dc..22728e2 100644 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CoroutineContextTest.kt +++ b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CoroutineContextTest.kt @@ -11,7 +11,7 @@ class CoroutineContextTest : FunSpec() { init { test("the calling context should be used by default for caches") { - val cache = Caffeine.newBuilder().asCache() + val cache = Caffeine.newBuilder().asCache() withContext(Hello()) { cache.get("foo") { "threadlocal=" + helloThreadLocal.get() @@ -24,7 +24,7 @@ class CoroutineContextTest : FunSpec() { } test("the calling context should be used by default for loading caches") { - val cache = Caffeine.newBuilder().asLoadingCache { "yahoo" } + val cache = Caffeine.newBuilder().asLoadingCache { "yahoo" } withContext(Hello()) { cache.get("foo") { "$it=" + helloThreadLocal.get() @@ -35,31 +35,6 @@ class CoroutineContextTest : FunSpec() { } shouldBe mapOf("foo" to "foo=hello") } } - - test("the default scope should be used when delegating to the default builder") { - val cache = cacheBuilder().build { - "$it=" + helloThreadLocal.get() - } - withContext(Hello()) { - cache.get("foo") { - "$it=" + helloThreadLocal.get() - } shouldBe "foo=hello" - cache.get("bar") shouldBe "bar=null" - } - } - - test("the calling context should not be used when useCallingContext is false") { - - val cache = cacheBuilder { - useCallingContext = false - }.build() - - withContext(Hello()) { - cache.get("foo") { - "threadlocal=" + helloThreadLocal.get() - } shouldBe "threadlocal=null" - } - } } } diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CustomDispatcherTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CustomDispatcherTest.kt deleted file mode 100644 index 6fbc0c7..0000000 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/CustomDispatcherTest.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.sksamuel.aedile.core - -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.shouldBe -import io.kotest.matchers.string.shouldContain -import kotlinx.coroutines.asCoroutineDispatcher -import java.util.concurrent.Executors - -class CustomDispatcherTest : FunSpec() { - init { - - test("Cache should use custom dispatcher") { - - val dispatcher = Executors.newCachedThreadPool { r -> - val t = Thread(r) - t.name = "mcthreadface" - t - }.asCoroutineDispatcher() - - val cache = caffeineBuilder { - this.dispatcher = dispatcher - }.build() - cache.get("foo") { - Thread.currentThread().name shouldContain "mcthreadface" - "bar" - } shouldBe "bar" - } - - test("LoadingCache should use custom dispatcher") { - - val dispatcher = Executors.newCachedThreadPool { r -> - val t = Thread(r) - t.name = "mcthreadface" - t - }.asCoroutineDispatcher() - - val cache = caffeineBuilder { - this.dispatcher = dispatcher - }.build { - Thread.currentThread().name shouldContain "mcthreadface" - "bar" - } - cache.get("foo") shouldBe "bar" - } - } -} diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/KeyLoaderTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/KeyLoaderTest.kt deleted file mode 100644 index 5920c4e..0000000 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/KeyLoaderTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.sksamuel.aedile.core - -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.shouldBe -import kotlinx.coroutines.delay - -class KeyLoaderTest : FunSpec() { - init { - - test("cache should use custom key loader") { - val cache = caffeineBuilder().build() - cache.get("foo") { - "bar" - } shouldBe "bar" - } - - test("cache should use support suspendable functions in the key loader") { - val cache = caffeineBuilder().build() - cache.get("foo") { - delay(1) - "bar" - } shouldBe "bar" - } - } -} diff --git a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/LoadingCacheTest.kt b/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/LoadingCacheTest.kt deleted file mode 100644 index fe51522..0000000 --- a/aedile-core/src/test/kotlin/com/sksamuel/aedile/core/LoadingCacheTest.kt +++ /dev/null @@ -1,315 +0,0 @@ -package com.sksamuel.aedile.core - -import io.kotest.assertions.throwables.shouldNotThrowAny -import io.kotest.assertions.throwables.shouldThrow -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.nulls.shouldBeNull -import io.kotest.matchers.shouldBe -import kotlinx.coroutines.delay -import kotlinx.coroutines.supervisorScope -import kotlinx.coroutines.yield -import java.util.concurrent.atomic.AtomicInteger -import kotlin.time.Duration.Companion.milliseconds - -class LoadingCacheTest : FunSpec() { - init { - - test("LoadingCache should use support suspendable loading function") { - val cache = cacheBuilder().build { - delay(1) - "bar" - } - cache.get("else") shouldBe "bar" - } - - test("LoadingCache should use support suspendable multiple keys loading function") { - val cache = cacheBuilder().buildAll { - delay(1) - mapOf("tweedle" to "dee", "twuddle" to "dum") - } - cache.get("tweedle") shouldBe "dee" - cache.get("twuddle") shouldBe "dum" - } - - test("LoadingCache should support simple puts") { - val cache = cacheBuilder().build() - cache.put("foo", "bar") - cache["baz"] = "waz" - cache.getIfPresent("foo") shouldBe "bar" - cache.getIfPresent("baz") shouldBe "waz" - } - - test("LoadingCache should support getOrPut") { - - val cache = cacheBuilder().build { - delay(1) - "bar" - } - - cache.get("foo") { - delay(1) - "wibble" - } shouldBe "wibble" - - cache.get("foo") { - delay(1) - "wobble" - } shouldBe "wibble" - } - - test("get should throw if build compute function throws and key is missing") { - val cache = cacheBuilder().build { - error("kaput") - } - shouldThrow { - cache.get("foo") - } - } - - test("Cache should support getOrNull with compute") { - val cache = cacheBuilder().build { "boo" } - cache.getOrNull("foo") { - yield() - "bar" - } shouldBe "bar" - val key = "baz" - cache.getOrNull(key) { null }.shouldBeNull() - cache.getOrNull(key) { "new value" }.shouldBe("new value") - cache.getOrNull(key) { "new value 2" }.shouldBe("new value") - cache.getOrNull(key) { null }.shouldBe("new value") - shouldNotThrowAny { cache.getOrNull(key) { error("kapow") } } - } - - test("getIfPresent should return null if build compute function throws and key is missing") { - val cache = cacheBuilder().build { - error("kaput") - } - cache.getIfPresent("foo") shouldBe null - } - - test("get should use existing value if build compute function throws and key is present") { - val cache = cacheBuilder().build { - error("kaput") - } - cache.get("foo") { "bar" } shouldBe "bar" - cache.get("foo") shouldBe "bar" - } - - test("get should propagate exceptions if the override throws") { - val cache = cacheBuilder().buildAll { keys -> - keys.associateWith { "$it-value" } - } - shouldThrow { - supervisorScope { - cache.get("foo") { error("kapow") } - } - } - } - - test("!getAll should throw if build compute function throws and any key is missing") { - val cache = cacheBuilder().build { - error("kaput") - } - shouldThrow { - supervisorScope { - cache.getAll(setOf("foo", "bar")) - } - } - cache.get("foo") { "baz" } shouldBe "baz" - shouldThrow { - supervisorScope { - cache.getAll(setOf("bar")) - } - } - cache.getAll(setOf("foo")) shouldBe mapOf("foo" to "baz") - } - - test("getAll should throw if build compute function override throws and any key is missing") { - val cache = cacheBuilder().build { - "$it-value" - } - shouldThrow { - supervisorScope { - cache.getAll(setOf("foo", "bar")) { error("boom") } - } - } - cache.getAll(setOf("foo")) shouldBe mapOf("foo" to "foo-value") - shouldThrow { - supervisorScope { - cache.getAll(setOf("foo", "bar")) { error("boom") } - } - } - } - - test("getAll should return existing values if the build function throws but values are present") { - val cache = cacheBuilder().build { - error("kaput") - } - cache.get("foo") { "baz" } shouldBe "baz" - cache.get("bar") { "faz" } shouldBe "faz" - cache.getAll(setOf("foo", "bar")) shouldBe mapOf("foo" to "baz", "bar" to "faz") - } - - test("LoadingCache should propagate exceptions in the build compute function override") { - val cache = cacheBuilder().build { - delay(1) - "bar" - } - shouldThrow { - supervisorScope { - cache.get("foo") { - error("kapow") - } - } - } - cache.get("bar") { "baz" } shouldBe "baz" - } - - test("LoadingCache should propagate exceptions in the buildAll compute function override") { - val cache = cacheBuilder().buildAll { keys -> - keys.associateWith { "$it-value" } - } - shouldThrow { - supervisorScope { - cache.get("foo") { - error("kapow") - } - } - } - cache.get("bar") { "baz" } shouldBe "baz" - } - - test("LoadingCache should support suspendable put") { - val cache = cacheBuilder().build { - delay(1) - "bar" - } - cache.put("foo") { - delay(1) - "wibble" - } - cache.get("foo") shouldBe "wibble" - cache.get("else") shouldBe "bar" - } - - test("LoadingCache should support getAll") { - val cache = cacheBuilder().build { - delay(1) - "bar" - } - cache.put("foo") { - delay(1) - "wobble" - } - cache.put("bar") { - delay(1) - "wibble" - } - cache.put("baz") { - delay(1) - "wubble" - } - cache.getAll(listOf("foo", "bar")) shouldBe mapOf("foo" to "wobble", "bar" to "wibble") - } - - test("getAll should support suspendable multiple keys loading function override") { - val cache = cacheBuilder().buildAll { - delay(1) - mapOf("tweedle" to "dee", "twuddle" to "dum") - } - cache.get("tweedle") shouldBe "dee" - cache.get("twuddle") shouldBe "dum" - cache.getAll(setOf("wibble", "wobble")) { keys -> - keys.associateWith { "$it-value" } - } shouldBe mapOf( - "wibble" to "wibble-value", - "wobble" to "wobble-value" - ) - } - - test("LoadingCache should support refreshAfterWrite using refresh compute function") { - val value = AtomicInteger(0) - val cache = cacheBuilder { - refreshAfterWrite = 10.milliseconds - }.build({ value.get() }, { _, _ -> - value.incrementAndGet() - }) - cache.get("foo") - cache.get("foo") - value.get() shouldBe 0 - delay(100) - cache.get("foo") - delay(100) - value.get() shouldBe 1 - delay(100) - cache.get("foo") - delay(100) - value.get() shouldBe 2 - } - - test("LoadingCache should support asMap") { - val cache = cacheBuilder().build { - delay(1) - "bar" - } - cache.put("foo") { - delay(1) - "wobble" - } - cache.put("bar") { - delay(1) - "wibble" - } - cache.asMap() shouldBe mapOf("foo" to "wobble", "bar" to "wibble") - } - - test("LoadingCache should support asDeferredMap") { - val cache = cacheBuilder().build { - delay(1) - "bar" - } - cache.put("wibble") { - delay(1) - "wobble" - } - cache.put("bubble") { - delay(1) - "bobble" - } - val map = cache.asDeferredMap() - map["wibble"]?.await() shouldBe "wobble" - map["bubble"]?.await() shouldBe "bobble" - } - - test("LoadingCache.getIfPresent") { - val cache = cacheBuilder().build { - delay(1) - "bar" - } - cache.getIfPresent("foo") shouldBe null - cache.put("foo") { "baz" } - cache.getIfPresent("foo") shouldBe "baz" - } - - test("Cache should support invalidate") { - val cache: LoadingCache = cacheBuilder().build { - delay(1) - "bar" - } - cache.put("wibble", "wobble") - cache.getIfPresent("wibble") shouldBe "wobble" - cache.invalidate("wibble") - cache.getIfPresent("wibble") shouldBe null - } - - test("Cache should support contains") { - val cache: LoadingCache = cacheBuilder().build { - delay(1) - "bar" - } - cache.put("wibble", "wobble") - cache.contains("wibble") shouldBe true - cache.contains("bubble") shouldBe false - } - } -} diff --git a/aedile-micrometer/build.gradle.kts b/aedile-micrometer/build.gradle.kts deleted file mode 100644 index e2b55a1..0000000 --- a/aedile-micrometer/build.gradle.kts +++ /dev/null @@ -1,9 +0,0 @@ -plugins { - id("kotlin-conventions") - id("publishing-conventions") -} - -dependencies { - api(projects.aedileCore) - api(libs.micrometer.core) -} diff --git a/aedile-micrometer/src/main/kotlin/com/sksamuel/aedile/micrometer/CacheMetrics.kt b/aedile-micrometer/src/main/kotlin/com/sksamuel/aedile/micrometer/CacheMetrics.kt deleted file mode 100644 index 6151cc4..0000000 --- a/aedile-micrometer/src/main/kotlin/com/sksamuel/aedile/micrometer/CacheMetrics.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.sksamuel.aedile.micrometer - -import com.sksamuel.aedile.core.Cache -import com.sksamuel.aedile.core.LoadingCache -import io.micrometer.core.instrument.MeterRegistry -import io.micrometer.core.instrument.Tag -import io.micrometer.core.instrument.binder.MeterBinder -import io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics - -@Deprecated("Use CaffeineCacheMetrics directly") -class CacheMetrics( - private val cache: Cache, - private val cacheName: String, - private val tags: Collection = emptyList() -) : MeterBinder { - - override fun bindTo(registry: MeterRegistry) { - cache.underlying().synchronous().stats() - CaffeineCacheMetrics(cache.underlying().synchronous(), cacheName, tags).bindTo(registry) - } -} - -@Deprecated("Use CaffeineCacheMetrics directly") -class LoadingCacheMetrics( - private val cache: LoadingCache, - private val cacheName: String, - private val tags: Collection = emptyList() -) : MeterBinder { - - override fun bindTo(registry: MeterRegistry) { - CaffeineCacheMetrics(cache.underlying().synchronous(), cacheName, tags).bindTo(registry) - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index c925691..15731e5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -9,7 +9,6 @@ rootProject.name = "aedile" include( "aedile-core", - "aedile-micrometer", ) enableFeaturePreview("STABLE_CONFIGURATION_CACHE") @@ -29,7 +28,6 @@ dependencyResolutionManagement { library("coroutines-jdk8", "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutines") library("caffeine", "com.github.ben-manes.caffeine:caffeine:3.2.2") - library("micrometer-core", "io.micrometer:micrometer-core:1.14.0") } } }