The sweetest fruit salad recipe for energy saving services
Chapter 6. Caching
(This story begins in Chapter 0. Launching an energy-saving rocket to the stars)
Our service receives IoT trends that come every hour from a large number of hardware devices, which do not change very often. One of the steps in our service logic consists of retrieving the datasource assigned to the IoT device. Since it would result in a call to our API for each device and hour, based on the initial assumption, we decided to add a client-side cache to keep this configuration and therefore avoid calling our API unnecessarily.
We are using Caffeine, a client-side cache, configured as follows:
In our maven’s pom file:
And defining injection as configuration:
@Bean
open fun caffeineCache(datasourcesCacheConfiguration: DatasourcesCacheConfiguration)
: Cache<String, SimpleDataSource> =
Caffeine.newBuilder()
.initialCapacity(initialCapacity)
.maximumSize(maximumSize)
.expireAfterWrite(24, TimeUnit.HOURS)
.recordStats()
.build()
At this point, we agreed to keep each cache element during one day. After that, a new trend of such device will perform a real call to the API. This way we considerably increase the performance of our component but, more important, we protect our internal service of thousands of unnecessary hourly calls.
Cache is injected when constructing our repository, and used as follows:
override fun lookup(deviceId: String): Mono<SimpleDataSource> {val cachedDataSource: SimpleDataSource? = cache.getIfPresent(deviceId)return if (cachedDataSource != null) {
Mono.just(cachedDataSource)
} else {
performGet(deviceId)
.map { dataSources ->
val simpleDataSource = SimpleDataSource(dataSources.firstOrNull())
cache.put(deviceId, simpleDataSource)
simpleDataSource
}
}
}
Our trip continues in Chapter 7. Human-friendly software lifecycle where we explain how we used Cucumber as a BDD adoption with Kotlin