Skip to content

Commit

Permalink
Migration to Pekko
Browse files Browse the repository at this point in the history
  • Loading branch information
KarelCemus committed Feb 4, 2024
1 parent dd96717 commit fd8f6d1
Show file tree
Hide file tree
Showing 31 changed files with 57 additions and 72 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@

## Changelog

### [:link: 4.0.0](https://github.com/KarelCemus/play-redis/tree/4.0.0-M1)

Migration to Pekko and Play 3.0, thanks to @TomJKing for help in [#272](https://github.com/KarelCemus/play-redis/pull/272),
finished in [#278](https://github.com/KarelCemus/play-redis/pull/278)

### [:link: 3.0.0](https://github.com/KarelCemus/play-redis/tree/3.0.0-M1)

Updated to Play `2.9.0` and dropped `Scala 2.12` since it was discontinued from the Play framework.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ operations. Besides the basic methods such as `get`, `set`
and `remove`, it provides more convenient methods such as
`expire`, `exists`, `invalidate` and much more.

The implementation builds on the top of Akka actor system,
The implementation builds on the top of Pekko actor system,
it is **completely non-blocking and asynchronous** under
the hood, though it also provides blocking APIs to ease
the use. Furthermore, the library supports several configuration
Expand All @@ -51,9 +51,9 @@ as well as on your premise.
- support of [standalone, cluster,](https://github.com/KarelCemus/play-redis/blob/3.0.0-M3/doc/20-configuration.md#standalone-vs-cluster)
[aws-cluster,](https://github.com/KarelCemus/play-redis/blob/3.0.0-M3/doc/20-configuration.md#aws-cluster)
and [sentinel modes](https://github.com/KarelCemus/play-redis/blob/3.0.0-M3/doc/20-configuration.md#sentinel)
- build on the top of Akka actors and serializers, [agnostic to the serialization mechanism](https://github.com/KarelCemus/play-redis/blob/3.0.0-M3/doc/20-configuration.md#limitation-of-data-serialization)
- build on the top of Pekko actors and serializers, [agnostic to the serialization mechanism](https://github.com/KarelCemus/play-redis/blob/3.0.0-M3/doc/20-configuration.md#limitation-of-data-serialization)
- for simplicity, it uses deprecated Java serialization by default
- it is recommended to use [Kryo library](https://github.com/romix/akka-kryo-serialization) or any other mechanism
- it is recommended to use [Kryo library](https://github.com/romix/akka-kryo-serialization) or any other mechanism


## Provided APIs
Expand Down
6 changes: 3 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ playVersion := "3.0.0"

libraryDependencies ++= Seq(
// play framework cache API
"org.playframework" %% "play-cache" % playVersion.value % Provided,
"org.playframework" %% "play-cache" % playVersion.value % Provided,
// redis connector
"io.github.rediscala" %% "rediscala" % "1.14.0-pekko",
"io.github.rediscala" %% "rediscala" % "1.14.0-pekko",
// test framework with mockito extension
"org.scalatest" %% "scalatest" % "3.2.17" % Test,
"org.scalamock" %% "scalamock" % "5.2.0" % Test,
// test module for play framework
"org.playframework" %% "play-test" % playVersion.value % Test,
"org.playframework" %% "play-test" % playVersion.value % Test,
// to run integration tests
"com.dimafeng" %% "testcontainers-scala-core" % "0.41.2" % Test,
)
Expand Down
20 changes: 10 additions & 10 deletions doc/20-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,8 @@ it uses `JavaSerializer` by default.
Since Akka 2.4.1, default `JavaSerializer` is [officially considered inefficient for production use](https://github.com/akka/akka/pull/18552).
Nevertheless, to keep things simple, play-redis **still uses this inefficient serializer NOT to enforce** any serialization
library to end users. Although, it recommends [kryo serializer](https://github.com/romix/akka-kryo-serialization) claiming
great performance and small output stream. Any serialization library can be smoothly connected through Akka
configuration, see the [official Akka documentation](https://doc.akka.io/docs/akka/current/scala/serialization.html).
great performance and small output stream. Any serialization library can be smoothly connected through Pekko
configuration, see the [official Pekko documentation](https://pekko.apache.org/docs/pekko/current/serialization.html).


## Overview
Expand All @@ -366,11 +366,11 @@ configuration, see the [official Akka documentation](https://doc.akka.io/docs/ak

### Instance-specific (can be locally overridden)

| Key | Type | Default | Description |
|----------------------------------------------------------|---------:|--------------------------------:|-------------------------------------|
| [play.cache.redis.source](#standalone-vs-cluster) | String | `standalone` | Defines the source of the configuration. Accepted values are `standalone`, `cluster`, `connection-string`, and `custom` |
| [play.cache.redis.sync-timeout](#timeout) | Duration | `1s` | conversion timeout applied by `SyncAPI` to convert `Future[T]` to `T`|
| [play.cache.redis.redis-timeout](#timeout) | Duration | `null` | waiting for the response from redis server |
| [play.cache.redis.prefix](#namespace-prefix) | String | `null` | optional namespace, i.e., key prefix |
| play.cache.redis.dispatcher | String | `akka.actor.default-dispatcher` | Akka actor |
| [play.cache.redis.recovery](#recovery-policy) | String | `log-and-default` | Defines behavior when command execution fails. For accepted values and more see |
| Key | Type | Default | Description |
|----------------------------------------------------------|---------:|-------------------------------------:|-------------------------------------------------------------------------------------------------------------------------|
| [play.cache.redis.source](#standalone-vs-cluster) | String | `standalone` | Defines the source of the configuration. Accepted values are `standalone`, `cluster`, `connection-string`, and `custom` |
| [play.cache.redis.sync-timeout](#timeout) | Duration | `1s` | conversion timeout applied by `SyncAPI` to convert `Future[T]` to `T` |
| [play.cache.redis.redis-timeout](#timeout) | Duration | `null` | waiting for the response from redis server |
| [play.cache.redis.prefix](#namespace-prefix) | String | `null` | optional namespace, i.e., key prefix |
| play.cache.redis.dispatcher | String | `pekko.actor.default-dispatcher` | Pekko actor |
| [play.cache.redis.recovery](#recovery-policy) | String | `log-and-default` | Defines behavior when command execution fails. For accepted values and more see |
2 changes: 1 addition & 1 deletion src/main/scala/play/api/cache/redis/RedisCacheModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class RedisCacheModule extends Module {
// common settings
val commons = Seq(
// bind serializer
bind[connector.PekkoSerializer].toProvider[connector.AkkaSerializerProvider],
bind[connector.PekkoSerializer].toProvider[connector.PekkoSerializerProvider],
bind[configuration.RedisInstanceResolver].to[GuiceRedisInstanceResolver],
)
// bind recovery resolver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import play.api.ConfigLoader

/**
* Configures non-connection related settings of redis instance, e.g.,
* synchronization timeout, Akka dispatcher, and recovery policy.
* synchronization timeout, Pekko dispatcher, and recovery policy.
*/
trait RedisSettings {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package play.api.cache.redis.connector

import play.api.cache.redis._

import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.serialization.{Serialization, SerializationExtension}
import play.api.cache.redis._

import java.util.Base64
import javax.inject._
Expand Down Expand Up @@ -45,10 +44,10 @@ trait PekkoSerializer {
}

/**
* Pekko encoder provides implementation of serialization using Pekko serializer.
* The implementation considers all primitives, nulls, and refs. This enables
* us to use Pekko settings to modify serializer mapping and use different
* serializers for different objects.
* Pekko encoder provides implementation of serialization using Pekko
* serializer. The implementation considers all primitives, nulls, and refs.
* This enables us to use Pekko settings to modify serializer mapping and use
* different serializers for different objects.
*/
private[connector] class PekkoEncoder(serializer: Serialization) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.connector

import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.actor.{ActorSystem, Scheduler}
import play.api.Logger
import play.api.cache.redis.configuration._
import play.api.inject.ApplicationLifecycle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package play.api.cache.redis.connector

import org.apache.pekko.actor.ActorSystem

import play.api.cache.redis._
import play.api.inject.ApplicationLifecycle

import javax.inject.Provider

/** Provides an instance of named redis connector */
private[redis] class RedisConnectorProvider(instance: RedisInstance, serializer: AkkaSerializer)(implicit system: ActorSystem, lifecycle: ApplicationLifecycle, runtime: RedisRuntime) extends Provider[RedisConnector] {
private[redis] class RedisConnectorProvider(instance: RedisInstance, serializer: PekkoSerializer)(implicit system: ActorSystem, lifecycle: ApplicationLifecycle, runtime: RedisRuntime) extends Provider[RedisConnector] {

private[connector] lazy val commands = new RedisCommandsProvider(instance).get

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package play.api.cache.redis.connector


import org.apache.pekko.actor.Scheduler
import org.apache.pekko.pattern.after
import redis._
Expand Down
2 changes: 0 additions & 2 deletions src/main/scala/play/api/cache/redis/impl/Builders.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package play.api.cache.redis.impl

import org.apache.pekko.pattern.AskTimeoutException

import scala.concurrent.Future

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package play.api.cache.redis.impl

import org.apache.pekko.Done
import play.api.Environment
import play.api.cache.redis._

import org.apache.pekko.Done

import scala.concurrent.{ExecutionContext, Future}
import scala.reflect.ClassTag

Expand Down
2 changes: 0 additions & 2 deletions src/main/scala/play/api/cache/redis/impl/RedisCaches.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package play.api.cache.redis.impl

import org.apache.pekko.actor.ActorSystem

import javax.inject.Provider
import play.api.Environment
import play.api.cache.redis._
import play.api.inject.ApplicationLifecycle
Expand Down
5 changes: 2 additions & 3 deletions src/main/scala/play/api/cache/redis/impl/RedisRuntime.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package play.api.cache.redis.impl

import play.api.cache.redis._

import org.apache.pekko.actor.ActorSystem
import play.api.cache.redis._

import scala.concurrent.ExecutionContext
import scala.concurrent.duration.FiniteDuration
Expand All @@ -24,7 +23,7 @@ final private[redis] case class RedisRuntimeImpl(
policy: RecoveryPolicy,
invocation: InvocationPolicy,
prefix: RedisPrefix,
timeout: org.apache.pekko.util.Timeout
timeout: org.apache.pekko.util.Timeout,
) extends RedisRuntime

private[redis] object RedisRuntime {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis

import akka.actor.ActorSystem
import org.apache.pekko.actor.ActorSystem
import play.api._
import play.api.cache.redis.test._
import play.api.inject.ApplicationLifecycle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package play.api.cache.redis


import org.apache.pekko.actor.ActorSystem
import play.api.cache.redis.configuration.{RedisHost, RedisSettings, RedisStandalone, RedisTimeouts}
import play.api.cache.redis.test._
Expand Down Expand Up @@ -134,7 +133,7 @@ class RedisCacheModuleSpec extends IntegrationSpec with RedisStandaloneContainer
password = None,
),
settings = RedisSettings(
dispatcher = "akka.actor.default-dispatcher",
dispatcher = "pekko.actor.default-dispatcher",
invocationPolicy = "lazy",
timeout = RedisTimeouts(1.second),
recovery = "log-and-default",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.connector

import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.actor.{ActorSystem, Scheduler}
import play.api.cache.redis.test._

import scala.concurrent.duration._
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.connector

import akka.actor.ActorSystem
import org.apache.pekko.actor.ActorSystem
import play.api.cache.redis._
import play.api.cache.redis.configuration._
import play.api.cache.redis.impl._
Expand Down Expand Up @@ -78,7 +78,7 @@ class RedisClusterSpec extends IntegrationSpec with RedisClusterContainer {
implicit val system: ActorSystem = ActorSystem("test", classLoader = Some(getClass.getClassLoader))
implicit val runtime: RedisRuntime = RedisRuntime("cluster", syncTimeout = 5.seconds, ExecutionContext.global, new LogAndFailPolicy, LazyInvocation)
implicit val application: StoppableApplication = StoppableApplication(system)
val serializer = new AkkaSerializerImpl(system)
val serializer = new PekkoSerializerImpl(system)

application.runAsyncInApplication {
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class RedisConnectorFailureSpec extends AsyncUnitSpec with ImplicitFutureMateria
private def test(name: String)(f: (SerializerAssertions, RedisCommandsMock, RedisConnector) => Future[Assertion]): Unit =
name in {
implicit val runtime: RedisRuntime = mock[RedisRuntime]
val serializer = mock[AkkaSerializer]
val serializer = mock[PekkoSerializer]
val commands = mock[RedisCommandsMock]
val connector: RedisConnector = new RedisConnectorImpl(serializer, commands)

Expand All @@ -253,7 +253,7 @@ class RedisConnectorFailureSpec extends AsyncUnitSpec with ImplicitFutureMateria
f(new SerializerAssertions(serializer), commands, connector)
}

private class SerializerAssertions(mock: AkkaSerializer) {
private class SerializerAssertions(mock: PekkoSerializer) {

def failOnEncode[T](value: T): Future[Unit] =
Future.successful {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package play.api.cache.redis.connector


import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.actor.{ActorSystem, Scheduler}
import play.api.cache.redis.test.{AsyncUnitSpec, StoppableApplication}
import redis.RedisCommand
import redis.protocol.RedisReply
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.connector

import akka.actor.ActorSystem
import org.apache.pekko.actor.ActorSystem
import org.scalatest.Ignore
import play.api.cache.redis._
import play.api.cache.redis.configuration._
Expand Down Expand Up @@ -66,7 +66,7 @@ class RedisSentinelSpec extends IntegrationSpec with RedisSentinelContainer {
implicit val system: ActorSystem = ActorSystem("test", classLoader = Some(getClass.getClassLoader))
implicit val runtime: RedisRuntime = RedisRuntime("sentinel", syncTimeout = 5.seconds, ExecutionContext.global, new LogAndFailPolicy, LazyInvocation)
implicit val application: StoppableApplication = StoppableApplication(system)
val serializer = new AkkaSerializerImpl(system)
val serializer = new PekkoSerializerImpl(system)

lazy val sentinelInstance = RedisSentinel(
name = "sentinel",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.connector

import akka.actor.ActorSystem
import org.apache.pekko.actor.ActorSystem
import play.api.cache.redis._
import play.api.cache.redis.configuration._
import play.api.cache.redis.impl._
Expand Down Expand Up @@ -587,7 +587,7 @@ class RedisStandaloneSpec extends IntegrationSpec with RedisStandaloneContainer
implicit val system: ActorSystem = ActorSystem("test", classLoader = Some(getClass.getClassLoader))
implicit val runtime: RedisRuntime = RedisRuntime("standalone", syncTimeout = 5.seconds, ExecutionContext.global, new LogAndFailPolicy, LazyInvocation)
implicit val application: StoppableApplication = StoppableApplication(system)
val serializer = new AkkaSerializerImpl(system)
val serializer = new PekkoSerializerImpl(system)

lazy val instance = RedisStandalone(
name = "play",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.connector

import akka.actor.ActorSystem
import org.apache.pekko.actor.ActorSystem
import play.api.cache.redis._
import play.api.cache.redis.test._

Expand Down Expand Up @@ -171,10 +171,10 @@ class SerializerSpec extends AsyncUnitSpec {
}
}

private def test(name: String)(f: AkkaSerializer => Unit): Unit =
private def test(name: String)(f: PekkoSerializer => Unit): Unit =
name in {
val system = ActorSystem.apply(s"test-${Random.nextInt()}", classLoader = Some(getClass.getClassLoader))
val serializer: AkkaSerializer = new AkkaSerializerImpl(system)
val serializer: PekkoSerializer = new PekkoSerializerImpl(system)
f(serializer)
system.terminate().map(_ => Passed)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package play.api.cache.redis.impl

import akka.Done
import org.scalamock.scalatest.AsyncMockFactoryBase
import play.api.cache.redis._

Expand Down
8 changes: 0 additions & 8 deletions src/test/scala/play/api/cache/redis/impl/BuildersSpec.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package play.api.cache.redis.impl


import org.apache.pekko.pattern.AskTimeoutException
import play.api.cache.redis._
import play.api.cache.redis.test._

Expand Down Expand Up @@ -107,12 +105,6 @@ class BuildersSpec extends AsyncUnitSpec with RedisRuntimeMock {
SynchronousBuilder.toResult(Task.infinite(), Task.resolved()) mustEqual Task.resolved.response
}

"recover from peko ask timeout" in new RuntimeMock {
runtime.policy returns failThrough
val actorFailure = Future.failed(new AskTimeoutException("Simulated actor ask timeout"))
SynchronousBuilder.toResult(actorFailure, Task.resolved()) mustEqual Task.resolved.response
}

"map value" in {
implicit val runtime: RedisRuntime = redisRuntime()
SynchronousBuilder.map(5)(_ + 5) mustEqual 10
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.impl

import akka.util.Timeout
import org.apache.pekko.util.Timeout
import org.scalamock.scalatest.AsyncMockFactoryBase
import play.api.cache.redis.{FailThrough, RecoverWithDefault, RecoveryPolicy, RedisException}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package play.api.cache.redis.impl

import akka.actor.ActorSystem
import org.apache.pekko.util..util.Timeout
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.util.Timeout
import play.api.cache.redis._
import play.api.cache.redis.configuration.{RedisHost, RedisStandalone}
import play.api.cache.redis.test.UnitSpec
Expand Down
4 changes: 2 additions & 2 deletions src/test/scala/play/api/cache/redis/test/BaseSpec.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package play.api.cache.redis.test

import akka.Done
import org.apache.pekko.Done
import org.scalactic.source.Position
import org.scalamock.scalatest.AsyncMockFactory
import org.scalatest._
Expand All @@ -23,7 +23,7 @@ trait DefaultValues {

val defaultsSettings: RedisSettingsTest =
RedisSettingsTest(
invocationContext = "akka.actor.default-dispatcher",
invocationContext = "pekko.actor.default-dispatcher",
invocationPolicy = "lazy",
timeout = RedisTimeouts(1.second, None, Some(500.millis)),
recovery = "log-and-default",
Expand Down
Loading

0 comments on commit fd8f6d1

Please sign in to comment.