SkillAgentSearch skills...

Rediscala

Redis client for Scala. fork from https://github.com/etaty/rediscala

Install / Use

/learn @rediscala/Rediscala
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

rediscala

scaladex

maven

A Redis client for Scala with non-blocking and asynchronous I/O operations.

  • Reactive : Redis requests/replies are wrapped in Futures.

  • Typesafe : Redis types are mapped to Scala types.

  • Fast : Rediscala uses redis pipelining. Blocking redis commands are moved into their own connection. A worker actor handles I/O operations (I/O bounds), another handles decoding of Redis replies (CPU bounds).

Set up your project dependencies

If you use SBT, you just have to edit build.sbt and add the following:

libraryDependencies += "io.github.rediscala" %% "rediscala" % "<version>"
<details><summary>old versions</summary>

From version 1.9.0:

  • use akka 2.5.23
  • released for scala
    • 2.11
    • 2.12
    • 2.13
libraryDependencies += "com.github.etaty" %% "rediscala" % "1.9.0"

From version 1.8.0:

  • use akka 2.4.12 (java 1.8)
  • released for scala 2.11 & 2.12
libraryDependencies += "com.github.etaty" %% "rediscala" % "1.8.0"

From version 1.3.1:

  • use akka 2.3
  • released for scala 2.10 & 2.11
libraryDependencies += "com.github.etaty" %% "rediscala" % "1.7.0"
</details>

Connect to the database

import redis.RedisClient
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import org.apache.pekko.actor.ActorSystem

object Main {
  def main(args: Array[String]): Unit = {
    given ActorSystem = ActorSystem()

    val redis = RedisClient()

    val futurePong = redis.ping()
    println("Ping sent!")
    futurePong.map(pong => {
      println(s"Redis replied with a $pong")
    })
    Await.result(futurePong, 5.seconds)

    system.shutdown()
  }
}

Basic Example

https://github.com/rediscala/rediscala-demo

You can fork with : git clone git@github.com:rediscala/rediscala-demo.git then run it, with sbt run

Redis Commands

All commands are supported :

Blocking commands

RedisBlockingClient is the instance allowing access to blocking commands :

  • blpop
  • brpop
  • brpopplush
  redisBlocking.blpop(Seq("workList", "otherKeyWithWork"), 5.seconds).map(result => {
    result.map({
      case (key, work) => println(s"list $key has work : ${work.utf8String}")
    })
  })

Full example: ExampleRediscalaBlocking

You can fork with: git clone git@github.com:rediscala/rediscala-demo.git then run it, with sbt run

Transactions

The idea behind transactions in Rediscala is to start a transaction outside of a redis connection. We use the TransactionBuilder to store call to redis commands (and for each command we give back a future). When exec is called, TransactionBuilder will build and send all the commands together to the server. Then the futures will be completed. By doing that we can use a normal connection with pipelining, and avoiding to trap a command from outside, in the transaction...

  val redisTransaction = redis.transaction() // new TransactionBuilder
  redisTransaction.watch("key")
  val set = redisTransaction.set("key", "abcValue")
  val decr = redisTransaction.decr("key")
  val get = redisTransaction.get("key")
  redisTransaction.exec()

Full example: ExampleTransaction

You can fork with : git clone git@github.com:rediscala/rediscala-demo.git then run it, with sbt run

TransactionsSpec will reveal even more gems of the API.

Pub/Sub

You can use a case class with callbacks RedisPubSub or extend the actor RedisSubscriberActor as shown in the example below

object ExamplePubSub {
  def main(args: Array[String]): Unit = {
    given ActorSystem = org.apache.pekko.actor.ActorSystem()

    val redis = RedisClient()

    // publish after 2 seconds every 2 or 5 seconds
    system.scheduler.schedule(2.seconds, 2.seconds)(redis.publish("time", System.currentTimeMillis()))
    system.scheduler.schedule(2.seconds, 5.seconds)(redis.publish("pattern.match", "pattern value"))
    // shutdown pekko in 20 seconds
    system.scheduler.scheduleOnce(20.seconds)(system.shutdown())

    val channels = Seq("time")
    val patterns = Seq("pattern.*")
    // create SubscribeActor instance
    system.actorOf(Props(classOf[SubscribeActor], channels, patterns).withDispatcher("rediscala.rediscala-client-worker-dispatcher"))
  }
}

class SubscribeActor(channels: Seq[String] = Nil, patterns: Seq[String] = Nil) extends RedisSubscriberActor(channels, patterns) {
  override val address: InetSocketAddress = new InetSocketAddress("localhost", 6379)

  def onMessage(message: Message) {
    println(s"message received: $message")
  }

  def onPMessage(pmessage: PMessage) {
    println(s"pattern message received: $pmessage")
  }
}

Full example: ExamplePubSub

You can fork with : git clone git@github.com:rediscala/rediscala-demo.git then run it, with sbt run

RedisPubSubSpec will reveal even more gems of the API.

Scripting

RedisScript is a helper, you can put your LUA script inside and it will compute the hash. You can use it with evalshaOrEval which run your script even if it wasn't already loaded.

  val redis = RedisClient()

  val redisScript = RedisScript("return 'rediscala'")

  val r = redis.evalshaOrEval(redisScript).map({
    case b: Bulk => println(b.toString())
  })
  Await.result(r, 5.seconds)

Full example: ExampleScripting

Redis Sentinel

SentinelClient connect to a redis sentinel server.

SentinelMonitoredRedisClient connect to a sentinel server to find the master addresse then start a connection. In case the master change your RedisClient connection will automatically connect to the new master server. If you are using a blocking client, you can use SentinelMonitoredRedisBlockingClient

Pool

RedisClientPool connect to a pool of redis servers. Redis commands are dispatched to redis connection in a round robin way.

Mas

View on GitHub
GitHub Stars20
CategoryDevelopment
Updated3d ago
Forks13

Languages

Scala

Security Score

95/100

Audited on Mar 26, 2026

No findings