Skip to content

Ahoo-Wang/CoCache

Repository files navigation

CoCache

Level 2 Distributed Coherence Cache Framework

License GitHub release Maven Central Codacy Badge codecov Integration Test Status

Architecture

Architecture

Installation

Use Gradle(Kotlin) to install dependencies

implementation("me.ahoo.cocache:cocache-spring-boot-starter")

Use Gradle(Groovy) to install dependencies

implementation 'me.ahoo.cocache:cocache-spring-boot-starter'

Use Maven to install dependencies

<dependency>
    <groupId>me.ahoo.cocache</groupId>
    <artifactId>cocache-spring-boot-starter</artifactId>
    <version>${cocache.version}</version>
</dependency>

Usage

classDiagram
direction BT
class Cache~K, V~ {
<<Interface>>
  + set(K, Long, V) Unit
  + getCache(K) CacheValue~V~?
  + set(K, Long, V) Unit
  + set(K, V) Unit
  + get(K) V?
  + set(K, V) Unit
  + get(K) V?
  + getTtlAt(K) Long?
  + setCache(K, CacheValue~V~) Unit
  + getTtlAt(K) Long?
  + evict(K) Unit
}
class CacheGetter~K, V~ {
<<Interface>>
  + get(K) V?
}
class CacheSource~K, V~ {
<<Interface>>
  + load(K) CacheValue~V~?
  + noOp() CacheSource~K, V~
}
class UserCache {
  + set(String, UserData) Unit
  + setCache(String, CacheValue~UserData~) Unit
  + getCache(String) CacheValue~UserData~?
  + evict(String) Unit
  + get(String) UserData?
  + getTtlAt(String) Long?
  + set(String, Long, UserData) Unit
}
class UserCacheSource {
  + load(String) CacheValue~UserData~?
}

Cache~K, V~  -->  CacheGetter~K, V~ 
UserCache  ..>  Cache~K, V~ 
UserCacheSource  ..>  CacheSource~K, V~ 
Loading
class UserCache(private val delegate: Cache<String, UserData>) :
    Cache<String, UserData> by delegate

@AutoConfiguration
class UserCacheAutoConfiguration {
    companion object {
        const val CACHE_KEY_PREFIX = "iam"
        const val USER_CACHE_BEAN_NAME = "userCache"
        const val USER_CACHE_SOURCE_BEAN_NAME = "${USER_CACHE_BEAN_NAME}Source"
    }

    @Bean
    @ConditionalOnMissingBean(name = [USER_CACHE_SOURCE_BEAN_NAME])
    fun userCacheSource(userClient: UserClient): CacheSource<String, UserData> {
        return UserCacheSource(userClient)
    }

    @Bean
    @ConditionalOnMissingBean
    fun userCache(
        @Qualifier(USER_CACHE_SOURCE_BEAN_NAME) cacheSource: CacheSource<String, UserData>,
        redisTemplate: StringRedisTemplate,
        cacheManager: CacheManager,
        clientIdGenerator: ClientIdGenerator
    ): UserCache {
        val clientId = clientIdGenerator.generate()
        val cacheKeyPrefix = "$CACHE_KEY_PREFIX:user:"
        val codecExecutor = ObjectToJsonCodecExecutor(UserData::class.java, redisTemplate, JsonSerializer)
        val distributedCaching: DistributedCache<UserData> = RedisDistributedCache(redisTemplate, codecExecutor)
        val delegate = cacheManager.getOrCreateCache(
            CacheConfig(
                cacheName = USER_CACHE_BEAN_NAME,
                clientId = clientId,
                keyConverter = ToStringKeyConverter(cacheKeyPrefix),
                distributedCaching = distributedCaching,
                cacheSource = cacheSource,
            ),
        )
        return UserCache(delegate)
    }
}

CoCache Get Sequence Diagram

CoCache-Get-Sequence-Diagram

JoinCache Get Sequence Diagram

JoinCache-Get-Sequence-Diagram