问题描述
我正在尝试实现请求缓存,以便尽可能避免昂贵的API调用。
目前,我已经使用Caffeine实现了缓存系统,如下所示:
@Service
class CacheService {
val playlistCache: Cache<String,Playlist> = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(30,TimeUnit.SECONDS)
.build()
fun queryPlaylistCache(playlistCacheKey: String) =
Mono.justOrEmpty(playlistCache.getIfPresent(playlistCacheKey)).map<Signal<out Playlist>> { Signal.next(it) }
val userSavedSongsCache: Cache<String,List<PlaylistOrUserSavedTrack>> = Caffeine.newBuilder().maximumSize(10_000).expireAfterWrite(30,TimeUnit.SECONDS).build()
}
@Service
class SpotifyRequestService(
val webClients: WebClients,val cacheService: CacheService
) {
fun getAPlaylist(Authorization: String,playlistId: String,fields: String?): Mono<Playlist> {
return CacheMono.lookup({ key: String -> cacheService.queryPlaylistCache(key) },"${playlistId}$fields")
.onCacheMissResume(
webClients.spotifyClientServiceClient.get()
.uri { uriBuilder: UriBuilder ->
uriBuilder.path("/playlists/{playlist_id}")
.queryParam("fields",fields ?: "")
.build(playlistId)
}
.header("Authorization",Authorization)
.retrieve()
.bodyToMono(Playlist::class.java)
)
.andWriteWith { key,value ->
Mono.fromRunnable { value?.get()?.let { cacheService.playlistCache.put(key,it) } } }
}
}
但是,据我了解,以这种方式实现缓存似乎不是最佳方法,因为获取/设置缓存是一项阻塞操作。
但是,在该线程中:Cache the result of a Mono from a WebClient call in a Spring WebFlux web application所选择的答案提到了为什么这是使用阻塞操作的可接受用例的原因。
有人能阐明什么是正确的解决方案吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)