All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.misk.redis.RedisModule.kt Maven / Gradle / Ivy

There is a newer version: 2024.11.14.031606-bddeae6
Show newest version
package misk.redis

import com.google.inject.Provides
import jakarta.inject.Singleton
import misk.ReadyService
import misk.ServiceModule
import misk.inject.KAbstractModule
import misk.metrics.v2.Metrics
import redis.clients.jedis.ConnectionPoolConfig
import redis.clients.jedis.JedisPoolConfig
import redis.clients.jedis.JedisPooled
import redis.clients.jedis.UnifiedJedis
import wisp.deployment.Deployment

/**
 * Configures a [Redis] client with metrics, this also installs a [ServiceModule] for [RedisService].
 * If other services require a working client connection to Redis before they can be used, specify a
 * dependency like:
 *
 * ```
 * install(ServiceModule()
 *     .dependsOn(keyOf())
 * )
 * ```
 *
 * You must pass in configuration for your Redis client.
 *
 * [redisReplicationGroupConfig]: Only one replication group config is supported.
 * An empty [RedisReplicationGroupConfig.redis_auth_password] is only permitted in fake
 * environments. See [Deployment].
 *
 * [connectionPoolConfig]: Misk-redis is backed by a [JedisPooled], you may not want to use the
 * [ConnectionPoolConfig] defaults! Be sure to understand them!
 *
 * See: https://github.com/xetorthio/jedis/wiki/Getting-started#using-jedis-in-a-multithreaded-environment
 */
class RedisModule @JvmOverloads constructor(
  private val redisReplicationGroupConfig: RedisReplicationGroupConfig,
  private val connectionPoolConfig: ConnectionPoolConfig,
  private val useSsl: Boolean = true,
) : KAbstractModule() {

  @Deprecated("Use ConnectionPoolConfig instead of JedisPoolConfig")
  constructor(
    redisConfig: RedisConfig,
    jedisPoolConfig: JedisPoolConfig,
    useSsl: Boolean = true,
  ) : this(
    getFirstReplicationGroup(redisConfig),
    connectionPoolConfig = jedisPoolConfig.toConnectionPoolConfig(),
    useSsl = useSsl
  )

  @Deprecated("Please use RedisReplicationGroupConfig to pass specific redis cluster configuration.")
  constructor(
    redisConfig: RedisConfig,
    connectionPoolConfig: ConnectionPoolConfig,
    useSsl: Boolean = true,
  ) : this(
    getFirstReplicationGroup(redisConfig),
    connectionPoolConfig = connectionPoolConfig,
    useSsl = useSsl,
  )

  override fun configure() {
    bind().toInstance(redisReplicationGroupConfig)
    install(ServiceModule().enhancedBy())
    requireBinding()
  }

  @Provides @Singleton
  internal fun provideRedisClient(
    clientMetrics: RedisClientMetrics,
    unifiedJedis: UnifiedJedis,
  ): Redis = RealRedis(unifiedJedis, clientMetrics)

  @Provides @Singleton
  internal fun provideUnifiedJedis(
    clientMetrics: RedisClientMetrics,
    redisReplicationGroupConfig: RedisReplicationGroupConfig,
    deployment: Deployment,
  ): UnifiedJedis {

    return JedisPooledWithMetrics(
      metrics = clientMetrics,
      poolConfig = connectionPoolConfig,
      replicationGroupConfig = redisReplicationGroupConfig,
      ssl = useSsl,
      requiresPassword = deployment.isReal
    )
  }

  companion object {
    private fun getFirstReplicationGroup(redisConfig: RedisConfig): RedisReplicationGroupConfig {
      // Get the first replication group, we only support 1 replication group per service.
      return redisConfig.values.firstOrNull()
        ?: throw RuntimeException("At least 1 replication group must be specified")
    }
  }
}

private fun JedisPoolConfig.toConnectionPoolConfig() = ConnectionPoolConfig().apply {
  maxTotal = [email protected]
  maxIdle = [email protected]
  minIdle = [email protected]
  blockWhenExhausted = [email protected]
  testOnCreate = [email protected]
  testOnBorrow = [email protected]
  testOnReturn = [email protected]
  testWhileIdle = [email protected]
  timeBetweenEvictionRuns = [email protected]
  minEvictableIdleTime = [email protected]
  setMaxWait([email protected])
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy