diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index cc448d86..87021b73 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -34,6 +34,7 @@ hikari = "5.1.0"
exposed = "0.44.1"
sqlite = "3.44.0.0"
mariadb = "3.3.0"
+caffeine = "3.1.8"
# gradle plugins
toxopid = "3.2.0"
@@ -81,6 +82,7 @@ exposed-java-time = { module = "org.jetbrains.exposed:exposed-java-time", versio
exposed-json = { module = "org.jetbrains.exposed:exposed-json", version.ref = "exposed" }
sqlite = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" }
mariadb = { module = "org.mariadb.jdbc:mariadb-java-client", version.ref = "mariadb" }
+caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
# gradle plugins
toxopid = { module = "fr.xpdustry:toxopid", version.ref = "toxopid" }
diff --git a/imperium-common/build.gradle.kts b/imperium-common/build.gradle.kts
index d183ad2c..5813cfbc 100644
--- a/imperium-common/build.gradle.kts
+++ b/imperium-common/build.gradle.kts
@@ -13,6 +13,7 @@ dependencies {
api(libs.rabbitmq.client)
api(libs.snowflake.id)
api(libs.okhttp)
+ api(libs.caffeine)
api(libs.slf4j.api)
testApi(libs.slf4j.simple)
diff --git a/imperium-common/src/main/kotlin/com/xpdustry/imperium/common/misc/CaffeineExtensions.kt b/imperium-common/src/main/kotlin/com/xpdustry/imperium/common/misc/CaffeineExtensions.kt
new file mode 100644
index 00000000..9430f02b
--- /dev/null
+++ b/imperium-common/src/main/kotlin/com/xpdustry/imperium/common/misc/CaffeineExtensions.kt
@@ -0,0 +1,46 @@
+/*
+ * Imperium, the software collection powering the Xpdustry network.
+ * Copyright (C) 2023 Xpdustry
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.xpdustry.imperium.common.misc
+
+import com.github.benmanes.caffeine.cache.AsyncCache
+import com.github.benmanes.caffeine.cache.Caffeine
+import com.xpdustry.imperium.common.async.ImperiumScope
+import kotlin.time.Duration
+import kotlin.time.toJavaDuration
+import kotlinx.coroutines.async
+import kotlinx.coroutines.future.asCompletableFuture
+import kotlinx.coroutines.future.await
+
+fun buildAsyncCache(
+ expireAfterAccess: Duration? = null,
+ maximumSize: Long = -1
+): AsyncCache {
+ val builder = Caffeine.newBuilder()
+ if (expireAfterAccess != null) {
+ builder.expireAfterAccess(expireAfterAccess.toJavaDuration())
+ }
+ if (maximumSize > 0) {
+ builder.maximumSize(maximumSize)
+ }
+ return builder.buildAsync()
+}
+
+suspend fun AsyncCache.getSuspending(
+ key: K,
+ compute: suspend (K) -> V
+): V = get(key) { k, _ -> ImperiumScope.IO.async { compute(k) }.asCompletableFuture() }.await()
diff --git a/imperium-discord/build.gradle.kts b/imperium-discord/build.gradle.kts
index bf080208..4b46e336 100644
--- a/imperium-discord/build.gradle.kts
+++ b/imperium-discord/build.gradle.kts
@@ -52,6 +52,7 @@ tasks.shadowJar {
exclude(dependency(libs.exposed.jdbc.get()))
exclude(dependency(libs.sqlite.get()))
exclude(dependency(libs.mariadb.get()))
+ exclude(dependency(libs.caffeine.get()))
}
}
diff --git a/imperium-mindustry/build.gradle.kts b/imperium-mindustry/build.gradle.kts
index c0b55cf2..9e2764de 100644
--- a/imperium-mindustry/build.gradle.kts
+++ b/imperium-mindustry/build.gradle.kts
@@ -55,6 +55,7 @@ tasks.shadowJar {
exclude(dependency("com.sksamuel.hoplite:hoplite-.*:.*"))
exclude(dependency(libs.sqlite.get()))
exclude(dependency(libs.mariadb.get()))
+ exclude(dependency(libs.caffeine.get()))
}
}