1
1
package io.github.typesafegithub.workflows.jitbindingserver
2
2
3
+ import com.github.benmanes.caffeine.cache.Caffeine
4
+ import com.sksamuel.aedile.core.asLoadingCache
5
+ import com.sksamuel.aedile.core.refreshAfterWrite
3
6
import io.github.oshai.kotlinlogging.KotlinLogging.logger
7
+ import io.github.typesafegithub.workflows.actionbindinggenerator.domain.ActionCoords
4
8
import io.github.typesafegithub.workflows.actionbindinggenerator.domain.prettyPrintWithoutVersion
5
9
import io.github.typesafegithub.workflows.mavenbinding.buildPackageArtifacts
6
10
import io.github.typesafegithub.workflows.shared.internal.getGithubAuthToken
7
- import io.ktor.http.HttpStatusCode
8
11
import io.ktor.server.response.respondText
9
12
import io.ktor.server.routing.Route
10
13
import io.ktor.server.routing.Routing
11
14
import io.ktor.server.routing.get
12
15
import io.ktor.server.routing.route
16
+ import io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics
17
+ import io.micrometer.prometheusmetrics.PrometheusMeterRegistry
18
+ import kotlin.time.Duration.Companion.hours
13
19
14
20
private val logger = logger { }
15
21
16
- fun Routing.metadataRoutes () {
22
+ typealias MetadataResult = Result <Map <String , String >>
23
+
24
+ private val metadataCache =
25
+ Caffeine
26
+ .newBuilder()
27
+ .refreshAfterWrite(1 .hours)
28
+ .recordStats()
29
+ .asLoadingCache<ActionCoords , MetadataResult > {
30
+ runCatching {
31
+ it.buildPackageArtifacts(githubAuthToken = getGithubAuthToken())
32
+ }
33
+ }
34
+
35
+ fun Routing.metadataRoutes (prometheusRegistry : PrometheusMeterRegistry ) {
36
+ CaffeineCacheMetrics .monitor(prometheusRegistry, metadataCache.underlying(), " metadata_cache" )
37
+
17
38
route(" {owner}/{name}/{file}" ) {
18
39
metadata()
19
40
}
@@ -25,21 +46,26 @@ fun Routing.metadataRoutes() {
25
46
26
47
private fun Route.metadata (refresh : Boolean = false) {
27
48
get {
28
- if (refresh && ! deliverOnRefreshRoute) return @get call.respondNotFound()
29
-
30
- val file = call.parameters[" file" ] ? : return @get call.respondNotFound()
31
49
val actionCoords = call.parameters.extractActionCoords(extractVersion = false )
32
50
33
51
logger.info { " ➡️ Requesting metadata for ${actionCoords.prettyPrintWithoutVersion} " }
34
52
35
- val bindingArtifacts = actionCoords.buildPackageArtifacts(githubAuthToken = getGithubAuthToken())
36
- if (file in bindingArtifacts) {
37
- when (val artifact = bindingArtifacts[file]) {
53
+ if (refresh) {
54
+ metadataCache.invalidate(actionCoords)
55
+ }
56
+ val metadataArtifacts = metadataCache.get(actionCoords).getOrThrow()
57
+
58
+ if (refresh && ! deliverOnRefreshRoute) return @get call.respondText(text = " OK" )
59
+
60
+ val file = call.parameters[" file" ] ? : return @get call.respondNotFound()
61
+
62
+ if (file in metadataArtifacts) {
63
+ when (val artifact = metadataArtifacts[file]) {
38
64
is String -> call.respondText(text = artifact)
39
- else -> call.respondText(text = " Not found " , status = HttpStatusCode . NotFound )
65
+ else -> call.respondNotFound( )
40
66
}
41
67
} else {
42
- call.respondText(text = " Not found " , status = HttpStatusCode . NotFound )
68
+ call.respondNotFound( )
43
69
}
44
70
}
45
71
}
0 commit comments