Connecting to redis with vert.x and scala

Connecting to redis with vert.x and scala

redis is a fast in-memory key value store (with optional persistence). redis is available for unix and windwos systems, for productive systems the unix version is recommended, as the windows version is not tested for productive environments. This example demonstrates the access to a redis database with vert.x 3. The code is written in scala.

The first step is to add a dependency to the vert.x redis client:

<dependency>
       <groupId>io.vertx</groupId>
       <artifactId>vertx-redis-client</artifactId>
       <version>${vertx.version}</version>
</dependency>

Then we write a object to handle the connection and operations:

package org.bitbucket.bpark.scala

import io.vertx.core.json.JsonArray
import io.vertx.core.{AsyncResult, Handler, Vertx}
import io.vertx.redis.{RedisClient, RedisOptions}

import scala.collection.JavaConversions._

object RedisConnector {

  private val DEFAULT_REDIS = "127.0.0.1"
  private val REDIS_CONFIG = "redis"

  private var vertxOption: Option[Vertx] = None

  def init(vertx: Vertx) : Unit = {

    vertxOption match {
      case None => vertxOption = Some(vertx)
      case Some(s) => println("Already initialized")
    }

  }

  def keys(pattern: String, handler: List[String] => Unit): Unit = {
    implicit val redisClient = getRedisClient
    redisClient.keys(pattern, new Handler[AsyncResult[JsonArray]] {
      override def handle(asyncResult: AsyncResult[JsonArray]): Unit = {
        val result = asyncResult.result().getList.toList.map(_.toString)
        handler(result)
        closeConnection
      }
    })
  }

  def get(key: String, handler: String => Unit): Unit = {
    implicit val redisClient = getRedisClient
    redisClient.get(key, new Handler[AsyncResult[String]] {
      override def handle(asyncResult: AsyncResult[String]): Unit = {
        val result = asyncResult.result()
        handler(result)
        closeConnection
      }
    })
  }

  def set(key: String, value: String): Unit = {
    implicit val redisClient = getRedisClient
    redisClient.set(key, value, new Handler[AsyncResult[Void]] {
      override def handle(e: AsyncResult[Void]): Unit = closeConnection
    })
  }

  private def getRedisClient = {
    val context = vertxOption.get.getOrCreateContext()
    val config = context.config
    val redisHost = config.getString(REDIS_CONFIG, DEFAULT_REDIS)
    RedisClient.create(vertxOption.get, new RedisOptions().setHost(redisHost))
  }

  private def closeConnection(implicit redisClient: RedisClient): Unit = {
    val closeHandler = new Handler[AsyncResult[Void]] {
      override def handle(e: AsyncResult[Void]): Unit = {}
    }
    redisClient.close(closeHandler)
  }

}

The connection settings are defined in an optional json string "redis": "192.168.2.101" or set to defaults.

The connection then can be created and used:

RedisConnector.init(vertx)
RedisConnector.set("mykey", "myvalue")
RedisConnector.keys("user:*", result => {
        processUser(result)
})