From aab6bffb3e85a5e7cd947eeff08ae2ac8530f184 Mon Sep 17 00:00:00 2001 From: Karel Cemus Date: Mon, 5 Feb 2024 00:46:29 +0100 Subject: [PATCH] Migration to Pekko and Play 3.0 (#278) * Migrate from Akka to Pekko Version 3 of the Scala Play Framework no longer ships with Akka. See release note: https://www.playframework.com/documentation/3.0.x/Highlights30 When combining version 3 of the Scala Play Framework with the Redis Cache module it requires Akka leading to compatibility issues * Missed refactored naming from 'Akka' to 'Pekko' * Migration to Pekko --------- Co-authored-by: TomJKing --- CHANGELOG.md | 5 +++ README.md | 6 +-- build.sbt | 8 ++-- doc/20-configuration.md | 20 +++++----- project/build.properties | 2 +- .../java/play/cache/redis/AsyncCacheApi.java | 2 +- src/main/resources/reference.conf | 8 ++-- .../cache/redis/RedisCacheComponents.scala | 6 +-- .../api/cache/redis/RedisCacheModule.scala | 6 +-- .../redis/configuration/RedisSettings.scala | 2 +- ...Serializer.scala => PekkoSerializer.scala} | 40 +++++++++---------- .../cache/redis/connector/RedisCommands.scala | 2 +- .../redis/connector/RedisConnectorImpl.scala | 2 +- .../connector/RedisConnectorProvider.scala | 4 +- .../redis/connector/RequestTimeout.scala | 4 +- .../play/api/cache/redis/impl/Builders.scala | 2 +- .../cache/redis/impl/JavaCompatibility.scala | 8 ++-- .../api/cache/redis/impl/RedisCaches.scala | 4 +- .../api/cache/redis/impl/RedisRuntime.scala | 8 ++-- .../scala/play/api/cache/redis/impl/dsl.scala | 2 +- .../scala/play/api/cache/redis/package.scala | 4 +- src/test/resources/reference.conf | 6 +-- .../redis/RedisCacheComponentsSpec.scala | 2 +- .../cache/redis/RedisCacheModuleSpec.scala | 4 +- .../redis/connector/FailEagerlySpec.scala | 2 +- .../redis/connector/RedisClusterSpec.scala | 4 +- .../connector/RedisConnectorFailureSpec.scala | 4 +- .../connector/RedisRequestTimeoutSpec.scala | 2 +- .../redis/connector/RedisSentinelSpec.scala | 4 +- .../redis/connector/RedisStandaloneSpec.scala | 4 +- .../redis/connector/SerializerSpec.scala | 10 ++--- .../api/cache/redis/impl/AsyncRedisMock.scala | 1 - .../api/cache/redis/impl/BuildersSpec.scala | 7 ---- .../cache/redis/impl/RedisRuntimeMock.scala | 2 +- .../cache/redis/impl/RedisRuntimeSpec.scala | 4 +- .../play/api/cache/redis/test/BaseSpec.scala | 4 +- .../cache/redis/test/FakeApplication.scala | 2 +- .../api/cache/redis/test/RedisLogger.scala | 6 +-- .../redis/test/StoppableApplication.scala | 4 +- 39 files changed, 107 insertions(+), 110 deletions(-) rename src/main/scala/play/api/cache/redis/connector/{AkkaSerializer.scala => PekkoSerializer.scala} (84%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90dcfe1a..529fe8cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/README.md b/README.md index f87a42c6..4d89032f 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 diff --git a/build.sbt b/build.sbt index e5817d35..da353ca9 100644 --- a/build.sbt +++ b/build.sbt @@ -15,18 +15,18 @@ crossScalaVersions := Seq("2.13.12") //, "3.3.0" scalaVersion := crossScalaVersions.value.head -playVersion := "2.9.0" +playVersion := "3.0.0" libraryDependencies ++= Seq( // play framework cache API - "com.typesafe.play" %% "play-cache" % playVersion.value % Provided, + "org.playframework" %% "play-cache" % playVersion.value % Provided, // redis connector - "io.github.rediscala" %% "rediscala" % "1.14.0-akka", + "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 - "com.typesafe.play" %% "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, ) diff --git a/doc/20-configuration.md b/doc/20-configuration.md index c22a76aa..ffcbe0ce 100644 --- a/doc/20-configuration.md +++ b/doc/20-configuration.md @@ -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 @@ -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 | diff --git a/project/build.properties b/project/build.properties index e8a1e246..abbbce5d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.7 +sbt.version=1.9.8 diff --git a/src/main/java/play/cache/redis/AsyncCacheApi.java b/src/main/java/play/cache/redis/AsyncCacheApi.java index 27b185d0..3072bcc0 100644 --- a/src/main/java/play/cache/redis/AsyncCacheApi.java +++ b/src/main/java/play/cache/redis/AsyncCacheApi.java @@ -1,6 +1,6 @@ package play.cache.redis; -import akka.Done; +import org.apache.pekko.Done; import java.util.Arrays; import java.util.List; diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf index 75083091..00c526f1 100644 --- a/src/main/resources/reference.conf +++ b/src/main/resources/reference.conf @@ -224,13 +224,13 @@ play.cache.redis { # prefix: null - # akka dispatcher + # pekko dispatcher # # note: this is global definition, can be locally overriden for each # cache instance. To do so, redefine this property # under 'play.cache.redis.instances.instance-name.this-property'. # - dispatcher: akka.actor.default-dispatcher + dispatcher: pekko.actor.default-dispatcher # invocation policy applies in methods `getOrElse`. It determines # whether to wait until the `set` completes or return eagerly the @@ -288,9 +288,9 @@ play.cache.redis { } # ================== -# Akka configuration +# Pekko configuration # ================== -akka { +pekko { actor { serialization-bindings { diff --git a/src/main/scala/play/api/cache/redis/RedisCacheComponents.scala b/src/main/scala/play/api/cache/redis/RedisCacheComponents.scala index 22541d3e..10267af4 100644 --- a/src/main/scala/play/api/cache/redis/RedisCacheComponents.scala +++ b/src/main/scala/play/api/cache/redis/RedisCacheComponents.scala @@ -8,7 +8,7 @@ import play.api.{Configuration, Environment} * from configuration package

*/ trait RedisCacheComponents { - implicit def actorSystem: akka.actor.ActorSystem + implicit def actorSystem: org.apache.pekko.actor.ActorSystem implicit def applicationLifecycle: ApplicationLifecycle def configuration: Configuration def environment: Environment @@ -27,14 +27,14 @@ trait RedisCacheComponents { /** override this for providing a custom redis instance resolver */ implicit def redisInstanceResolver: RedisInstanceResolver = emptyInstanceResolver - private lazy val akkaSerializer: connector.AkkaSerializer = new connector.AkkaSerializerProvider().get + private lazy val pekkoSerializer: connector.PekkoSerializer = new connector.PekkoSerializerProvider().get private lazy val manager = configuration.get("play.cache.redis")(play.api.cache.redis.configuration.RedisInstanceManager) /** translates the cache name into the configuration */ private def redisInstance(name: String)(implicit resolver: RedisInstanceResolver): RedisInstance = manager.instanceOf(name).resolved(resolver) - private def cacheApi(instance: RedisInstance): impl.RedisCaches = new impl.RedisCachesProvider(instance, akkaSerializer, environment).get + private def cacheApi(instance: RedisInstance): impl.RedisCaches = new impl.RedisCachesProvider(instance, pekkoSerializer, environment).get def cacheApi(name: String)(implicit resolver: RedisInstanceResolver): RedisCaches = cacheApi(redisInstance(name)(resolver)) } diff --git a/src/main/scala/play/api/cache/redis/RedisCacheModule.scala b/src/main/scala/play/api/cache/redis/RedisCacheModule.scala index f2a75a22..ac56f93f 100644 --- a/src/main/scala/play/api/cache/redis/RedisCacheModule.scala +++ b/src/main/scala/play/api/cache/redis/RedisCacheModule.scala @@ -24,7 +24,7 @@ class RedisCacheModule extends Module { // common settings val commons = Seq( // bind serializer - bind[connector.AkkaSerializer].toProvider[connector.AkkaSerializerProvider], + bind[connector.PekkoSerializer].toProvider[connector.PekkoSerializerProvider], bind[configuration.RedisInstanceResolver].to[GuiceRedisInstanceResolver], ) // bind recovery resolver @@ -108,10 +108,10 @@ class GuiceRedisCacheProvider(instance: RedisInstanceProvider) extends Provider[ override lazy val get: RedisCaches = new impl.RedisCachesProvider( instance = instance.resolved(bind[configuration.RedisInstanceResolver]), - serializer = bind[connector.AkkaSerializer], + serializer = bind[connector.PekkoSerializer], environment = bind[play.api.Environment], )( - system = bind[akka.actor.ActorSystem], + system = bind[org.apache.pekko.actor.ActorSystem], lifecycle = bind[ApplicationLifecycle], recovery = bind[RecoveryPolicyResolver], ).get diff --git a/src/main/scala/play/api/cache/redis/configuration/RedisSettings.scala b/src/main/scala/play/api/cache/redis/configuration/RedisSettings.scala index 60b3ac17..be608985 100644 --- a/src/main/scala/play/api/cache/redis/configuration/RedisSettings.scala +++ b/src/main/scala/play/api/cache/redis/configuration/RedisSettings.scala @@ -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 { diff --git a/src/main/scala/play/api/cache/redis/connector/AkkaSerializer.scala b/src/main/scala/play/api/cache/redis/connector/PekkoSerializer.scala similarity index 84% rename from src/main/scala/play/api/cache/redis/connector/AkkaSerializer.scala rename to src/main/scala/play/api/cache/redis/connector/PekkoSerializer.scala index 007dd562..54c7c70a 100644 --- a/src/main/scala/play/api/cache/redis/connector/AkkaSerializer.scala +++ b/src/main/scala/play/api/cache/redis/connector/PekkoSerializer.scala @@ -1,7 +1,7 @@ package play.api.cache.redis.connector -import akka.actor.ActorSystem -import akka.serialization._ +import org.apache.pekko.actor.ActorSystem +import org.apache.pekko.serialization.{Serialization, SerializationExtension} import play.api.cache.redis._ import java.util.Base64 @@ -13,7 +13,7 @@ import scala.util._ * Provides a encode and decode methods to serialize objects into strings and * vise versa. */ -trait AkkaSerializer { +trait PekkoSerializer { /** * Method accepts a value to be serialized into the string. Based on the @@ -44,12 +44,12 @@ trait AkkaSerializer { } /** - * Akka encoder provides implementation of serialization using Akka serializer. - * The implementation considers all primitives, nulls, and refs. This enables - * us to use Akka 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 AkkaEncoder(serializer: Serialization) { +private[connector] class PekkoEncoder(serializer: Serialization) { /** Unsafe method encoding the given value into a string */ def encode(value: Any): String = value match { @@ -57,7 +57,7 @@ private[connector] class AkkaEncoder(serializer: Serialization) { case null => unsupported("Null is not supported by the redis cache connector.") // AnyVal is not supported by default, have to be implemented manually; also basic types are processed as primitives case primitive if isPrimitive(primitive) => primitive.toString - // AnyRef is supported by Akka serializers, but it does not consider classTag, thus it is done manually + // AnyRef is supported by Pekko serializers, but it does not consider classTag, thus it is done manually case anyRef: AnyRef => anyRefToString(anyRef) // $COVERAGE-OFF$ // if no of the cases above matches, throw an exception @@ -84,12 +84,12 @@ private[connector] class AkkaEncoder(serializer: Serialization) { } /** - * Akka decoder provides implementation of deserialization using Akka + * Pekko decoder provides implementation of deserialization using Pekko * serializer. The implementation considers all primitives, nulls, and refs. - * This enables us to use Akka settings to modify serializer mapping and use + * This enables us to use Pekko settings to modify serializer mapping and use * different serializers for different objects. */ -private[connector] class AkkaDecoder(serializer: Serialization) { +private[connector] class PekkoDecoder(serializer: Serialization) { import scala.reflect.{ClassTag => Scala} @@ -139,19 +139,19 @@ private[connector] class AkkaDecoder(serializer: Serialization) { } @Singleton -private[connector] class AkkaSerializerImpl @Inject() (system: ActorSystem) extends AkkaSerializer { +private[connector] class PekkoSerializerImpl @Inject() (system: ActorSystem) extends PekkoSerializer { /** * serializer dispatcher used to serialize the objects into bytes; the - * instance is retrieved from Akka based on its configuration + * instance is retrieved from Pekko based on its configuration */ protected val serializer: Serialization = SerializationExtension(system) - /** value serializer based on Akka serialization */ - private val encoder = new AkkaEncoder(serializer) + /** value serializer based on Pekko serialization */ + private val encoder = new PekkoEncoder(serializer) - /** value decoder based on Akka serialization */ - private val decoder = new AkkaDecoder(serializer) + /** value decoder based on Pekko serialization */ + private val decoder = new PekkoDecoder(serializer) /** * Method accepts a value to be serialized into the string. Based on the @@ -224,6 +224,6 @@ private[connector] object JavaClassTag { val String: ClassTag[String] = ClassTag(classOf[String]) } -class AkkaSerializerProvider @Inject() (implicit system: ActorSystem) extends Provider[AkkaSerializer] { - lazy val get = new AkkaSerializerImpl(system) +class PekkoSerializerProvider @Inject() (implicit system: ActorSystem) extends Provider[PekkoSerializer] { + lazy val get = new PekkoSerializerImpl(system) } diff --git a/src/main/scala/play/api/cache/redis/connector/RedisCommands.scala b/src/main/scala/play/api/cache/redis/connector/RedisCommands.scala index 22476c27..c90b33b5 100644 --- a/src/main/scala/play/api/cache/redis/connector/RedisCommands.scala +++ b/src/main/scala/play/api/cache/redis/connector/RedisCommands.scala @@ -1,6 +1,6 @@ package play.api.cache.redis.connector -import akka.actor.{ActorSystem, Scheduler} +import org.apache.pekko.actor.{ActorSystem, Scheduler} import play.api.Logger import play.api.cache.redis.configuration._ import play.api.inject.ApplicationLifecycle diff --git a/src/main/scala/play/api/cache/redis/connector/RedisConnectorImpl.scala b/src/main/scala/play/api/cache/redis/connector/RedisConnectorImpl.scala index 16b1ded1..85e6dd91 100644 --- a/src/main/scala/play/api/cache/redis/connector/RedisConnectorImpl.scala +++ b/src/main/scala/play/api/cache/redis/connector/RedisConnectorImpl.scala @@ -20,7 +20,7 @@ import scala.reflect.ClassTag * @param redis * implementation of the commands */ -private[connector] class RedisConnectorImpl(serializer: AkkaSerializer, redis: RedisCommands)(implicit runtime: RedisRuntime) extends RedisConnector { +private[connector] class RedisConnectorImpl(serializer: PekkoSerializer, redis: RedisCommands)(implicit runtime: RedisRuntime) extends RedisConnector { import ExpectedFuture._ diff --git a/src/main/scala/play/api/cache/redis/connector/RedisConnectorProvider.scala b/src/main/scala/play/api/cache/redis/connector/RedisConnectorProvider.scala index 31dc2984..c548544a 100644 --- a/src/main/scala/play/api/cache/redis/connector/RedisConnectorProvider.scala +++ b/src/main/scala/play/api/cache/redis/connector/RedisConnectorProvider.scala @@ -1,13 +1,13 @@ package play.api.cache.redis.connector -import akka.actor.ActorSystem +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 diff --git a/src/main/scala/play/api/cache/redis/connector/RequestTimeout.scala b/src/main/scala/play/api/cache/redis/connector/RequestTimeout.scala index 57c500b9..85aaf2c1 100644 --- a/src/main/scala/play/api/cache/redis/connector/RequestTimeout.scala +++ b/src/main/scala/play/api/cache/redis/connector/RequestTimeout.scala @@ -1,7 +1,7 @@ package play.api.cache.redis.connector -import akka.actor.Scheduler -import akka.pattern.after +import org.apache.pekko.actor.Scheduler +import org.apache.pekko.pattern.after import redis._ import scala.concurrent.duration._ diff --git a/src/main/scala/play/api/cache/redis/impl/Builders.scala b/src/main/scala/play/api/cache/redis/impl/Builders.scala index 4a45fc28..f1a0dacc 100644 --- a/src/main/scala/play/api/cache/redis/impl/Builders.scala +++ b/src/main/scala/play/api/cache/redis/impl/Builders.scala @@ -10,7 +10,7 @@ private object Builders { import dsl._ import play.api.cache.redis._ - import akka.pattern.AskTimeoutException + import org.apache.pekko.pattern.AskTimeoutException trait ResultBuilder[Result[_]] { diff --git a/src/main/scala/play/api/cache/redis/impl/JavaCompatibility.scala b/src/main/scala/play/api/cache/redis/impl/JavaCompatibility.scala index 39a03032..5a3c9dc0 100644 --- a/src/main/scala/play/api/cache/redis/impl/JavaCompatibility.scala +++ b/src/main/scala/play/api/cache/redis/impl/JavaCompatibility.scala @@ -1,6 +1,6 @@ package play.api.cache.redis.impl -import akka.Done +import org.apache.pekko.Done import play.api.Environment import play.api.cache.redis._ @@ -8,7 +8,7 @@ import scala.concurrent.{ExecutionContext, Future} import scala.reflect.ClassTag private[impl] object JavaCompatibility extends JavaCompatibilityBase { - import scala.compat.java8.{FutureConverters, OptionConverters} + import scala.jdk.javaapi.{FutureConverters, OptionConverters} type CompletionStage[T] = java.util.concurrent.CompletionStage[T] type Callable[T] = java.util.concurrent.Callable[T] @@ -28,7 +28,7 @@ private[impl] object JavaCompatibility extends JavaCompatibilityBase { } implicit class Java8Stage[T](private val future: Future[T]) extends AnyVal { - @inline def asJava: CompletionStage[T] = FutureConverters.toJava(future) + @inline def asJava: CompletionStage[T] = FutureConverters.asJava(future) @inline def asDone(implicit ec: ExecutionContext): Future[Done] = future.map(_ => Done) } @@ -41,7 +41,7 @@ private[impl] object JavaCompatibility extends JavaCompatibilityBase { } implicit class ScalaCompatibility[T](private val future: CompletionStage[T]) extends AnyVal { - @inline def asScala: Future[T] = FutureConverters.toScala(future) + @inline def asScala: Future[T] = FutureConverters.asScala(future) } implicit class RichFuture(private val future: Future.type) extends AnyVal { diff --git a/src/main/scala/play/api/cache/redis/impl/RedisCaches.scala b/src/main/scala/play/api/cache/redis/impl/RedisCaches.scala index 8ee47be1..de225f06 100644 --- a/src/main/scala/play/api/cache/redis/impl/RedisCaches.scala +++ b/src/main/scala/play/api/cache/redis/impl/RedisCaches.scala @@ -1,6 +1,6 @@ package play.api.cache.redis.impl -import akka.actor.ActorSystem +import org.apache.pekko.actor.ActorSystem import play.api.Environment import play.api.cache.redis._ import play.api.inject.ApplicationLifecycle @@ -21,7 +21,7 @@ trait RedisCaches { def javaAsync: play.cache.redis.AsyncCacheApi } -private[redis] class RedisCachesProvider(instance: RedisInstance, serializer: connector.AkkaSerializer, environment: Environment)(implicit system: ActorSystem, lifecycle: ApplicationLifecycle, recovery: RecoveryPolicyResolver) extends Provider[RedisCaches] { +private[redis] class RedisCachesProvider(instance: RedisInstance, serializer: connector.PekkoSerializer, environment: Environment)(implicit system: ActorSystem, lifecycle: ApplicationLifecycle, recovery: RecoveryPolicyResolver) extends Provider[RedisCaches] { import RedisRuntime._ implicit private lazy val runtime: RedisRuntime = RedisRuntime(instance, instance.recovery, instance.invocationPolicy, instance.prefix)(system) diff --git a/src/main/scala/play/api/cache/redis/impl/RedisRuntime.scala b/src/main/scala/play/api/cache/redis/impl/RedisRuntime.scala index 4fa65c0a..2c76c39e 100644 --- a/src/main/scala/play/api/cache/redis/impl/RedisRuntime.scala +++ b/src/main/scala/play/api/cache/redis/impl/RedisRuntime.scala @@ -1,6 +1,6 @@ package play.api.cache.redis.impl -import akka.actor.ActorSystem +import org.apache.pekko.actor.ActorSystem import play.api.cache.redis._ import scala.concurrent.ExecutionContext @@ -14,7 +14,7 @@ private[redis] trait RedisRuntime extends connector.RedisRuntime { implicit def policy: RecoveryPolicy implicit def invocation: InvocationPolicy implicit def prefix: RedisPrefix - implicit def timeout: akka.util.Timeout + implicit def timeout: org.apache.pekko.util.Timeout } final private[redis] case class RedisRuntimeImpl( @@ -23,7 +23,7 @@ final private[redis] case class RedisRuntimeImpl( policy: RecoveryPolicy, invocation: InvocationPolicy, prefix: RedisPrefix, - timeout: akka.util.Timeout, + timeout: org.apache.pekko.util.Timeout, ) extends RedisRuntime private[redis] object RedisRuntime { @@ -44,6 +44,6 @@ private[redis] object RedisRuntime { apply(instance.name, instance.timeout.sync, system.dispatchers.lookup(instance.invocationContext), recovery, invocation, prefix) def apply(name: String, syncTimeout: FiniteDuration, context: ExecutionContext, recovery: RecoveryPolicy, invocation: InvocationPolicy, prefix: RedisPrefix = RedisEmptyPrefix): RedisRuntime = - RedisRuntimeImpl(name, context, recovery, invocation, prefix, akka.util.Timeout(syncTimeout)) + RedisRuntimeImpl(name, context, recovery, invocation, prefix, org.apache.pekko.util.Timeout(syncTimeout)) } diff --git a/src/main/scala/play/api/cache/redis/impl/dsl.scala b/src/main/scala/play/api/cache/redis/impl/dsl.scala index 70215186..586fb706 100644 --- a/src/main/scala/play/api/cache/redis/impl/dsl.scala +++ b/src/main/scala/play/api/cache/redis/impl/dsl.scala @@ -49,7 +49,7 @@ private[impl] object dsl { } - /** maps units into akka.Done */ + /** maps units into org.apache.pekko.Done */ @inline private val unitAsDone: Any => Done = _ => Done /** applies prefixer to produce final cache key */ diff --git a/src/main/scala/play/api/cache/redis/package.scala b/src/main/scala/play/api/cache/redis/package.scala index 6c33049b..ec73bbe8 100644 --- a/src/main/scala/play/api/cache/redis/package.scala +++ b/src/main/scala/play/api/cache/redis/package.scala @@ -2,8 +2,8 @@ package play.api.cache package object redis extends AnyRef with ExpirationImplicits with ExceptionImplicits { - @inline type Done = akka.Done - @inline private[redis] val Done: Done = akka.Done + @inline type Done = org.apache.pekko.Done + @inline private[redis] val Done: Done = org.apache.pekko.Done type SynchronousResult[A] = A type AsynchronousResult[A] = scala.concurrent.Future[A] diff --git a/src/test/resources/reference.conf b/src/test/resources/reference.conf index 03486f3b..a8bcf51f 100644 --- a/src/test/resources/reference.conf +++ b/src/test/resources/reference.conf @@ -1,13 +1,13 @@ # ================== -# Akka configuration +# Pekko configuration # ================== -akka { +pekko { log-dead-letters = off log-dead-letters-during-shutdown = off actor { - # Akka 2.6 disables Java serialization by default + # Pekko disables Java serialization by default # and it must be explicitly enabled # # Java serialization is used in tests for its simplicity diff --git a/src/test/scala/play/api/cache/redis/RedisCacheComponentsSpec.scala b/src/test/scala/play/api/cache/redis/RedisCacheComponentsSpec.scala index b59c36df..f662aebc 100644 --- a/src/test/scala/play/api/cache/redis/RedisCacheComponentsSpec.scala +++ b/src/test/scala/play/api/cache/redis/RedisCacheComponentsSpec.scala @@ -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 diff --git a/src/test/scala/play/api/cache/redis/RedisCacheModuleSpec.scala b/src/test/scala/play/api/cache/redis/RedisCacheModuleSpec.scala index 48bce2e8..dc4fbd1a 100644 --- a/src/test/scala/play/api/cache/redis/RedisCacheModuleSpec.scala +++ b/src/test/scala/play/api/cache/redis/RedisCacheModuleSpec.scala @@ -1,6 +1,6 @@ package play.api.cache.redis -import akka.actor.ActorSystem +import org.apache.pekko.actor.ActorSystem import play.api.cache.redis.configuration.{RedisHost, RedisSettings, RedisStandalone, RedisTimeouts} import play.api.cache.redis.test._ import play.api.inject._ @@ -133,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", diff --git a/src/test/scala/play/api/cache/redis/connector/FailEagerlySpec.scala b/src/test/scala/play/api/cache/redis/connector/FailEagerlySpec.scala index 96c7da64..fe68c2c5 100644 --- a/src/test/scala/play/api/cache/redis/connector/FailEagerlySpec.scala +++ b/src/test/scala/play/api/cache/redis/connector/FailEagerlySpec.scala @@ -1,6 +1,6 @@ package play.api.cache.redis.connector -import akka.actor.{ActorSystem, Scheduler} +import org.apache.pekko.actor.{ActorSystem, Scheduler} import play.api.cache.redis.test._ import scala.concurrent.duration._ diff --git a/src/test/scala/play/api/cache/redis/connector/RedisClusterSpec.scala b/src/test/scala/play/api/cache/redis/connector/RedisClusterSpec.scala index a298c545..0dcf1212 100644 --- a/src/test/scala/play/api/cache/redis/connector/RedisClusterSpec.scala +++ b/src/test/scala/play/api/cache/redis/connector/RedisClusterSpec.scala @@ -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._ @@ -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 { diff --git a/src/test/scala/play/api/cache/redis/connector/RedisConnectorFailureSpec.scala b/src/test/scala/play/api/cache/redis/connector/RedisConnectorFailureSpec.scala index 681a4763..466d95e1 100644 --- a/src/test/scala/play/api/cache/redis/connector/RedisConnectorFailureSpec.scala +++ b/src/test/scala/play/api/cache/redis/connector/RedisConnectorFailureSpec.scala @@ -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) @@ -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 { diff --git a/src/test/scala/play/api/cache/redis/connector/RedisRequestTimeoutSpec.scala b/src/test/scala/play/api/cache/redis/connector/RedisRequestTimeoutSpec.scala index 8a7a1b24..b8053a96 100644 --- a/src/test/scala/play/api/cache/redis/connector/RedisRequestTimeoutSpec.scala +++ b/src/test/scala/play/api/cache/redis/connector/RedisRequestTimeoutSpec.scala @@ -1,6 +1,6 @@ package play.api.cache.redis.connector -import akka.actor.{ActorSystem, Scheduler} +import org.apache.pekko.actor.{ActorSystem, Scheduler} import play.api.cache.redis.test.{AsyncUnitSpec, StoppableApplication} import redis.RedisCommand import redis.protocol.RedisReply diff --git a/src/test/scala/play/api/cache/redis/connector/RedisSentinelSpec.scala b/src/test/scala/play/api/cache/redis/connector/RedisSentinelSpec.scala index ae0bfb80..de89feea 100644 --- a/src/test/scala/play/api/cache/redis/connector/RedisSentinelSpec.scala +++ b/src/test/scala/play/api/cache/redis/connector/RedisSentinelSpec.scala @@ -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._ @@ -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", diff --git a/src/test/scala/play/api/cache/redis/connector/RedisStandaloneSpec.scala b/src/test/scala/play/api/cache/redis/connector/RedisStandaloneSpec.scala index 2321fd7f..690fb0cd 100644 --- a/src/test/scala/play/api/cache/redis/connector/RedisStandaloneSpec.scala +++ b/src/test/scala/play/api/cache/redis/connector/RedisStandaloneSpec.scala @@ -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._ @@ -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", diff --git a/src/test/scala/play/api/cache/redis/connector/SerializerSpec.scala b/src/test/scala/play/api/cache/redis/connector/SerializerSpec.scala index 57d1e015..58ae80e5 100644 --- a/src/test/scala/play/api/cache/redis/connector/SerializerSpec.scala +++ b/src/test/scala/play/api/cache/redis/connector/SerializerSpec.scala @@ -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._ @@ -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) } @@ -184,11 +184,11 @@ class SerializerSpec extends AsyncUnitSpec { object SerializerSpec { implicit private class ValueEncoder(private val any: Any) extends AnyVal { - def encoded(implicit s: AkkaSerializer): String = s.encode(any).get + def encoded(implicit s: PekkoSerializer): String = s.encode(any).get } implicit private class StringDecoder(private val string: String) extends AnyVal { - def decoded[T: ClassTag](implicit s: AkkaSerializer): T = s.decode[T](string).get + def decoded[T: ClassTag](implicit s: PekkoSerializer): T = s.decode[T](string).get } implicit private class StringOps(private val string: String) extends AnyVal { diff --git a/src/test/scala/play/api/cache/redis/impl/AsyncRedisMock.scala b/src/test/scala/play/api/cache/redis/impl/AsyncRedisMock.scala index 6365e883..ae660476 100644 --- a/src/test/scala/play/api/cache/redis/impl/AsyncRedisMock.scala +++ b/src/test/scala/play/api/cache/redis/impl/AsyncRedisMock.scala @@ -1,6 +1,5 @@ package play.api.cache.redis.impl -import akka.Done import org.scalamock.scalatest.AsyncMockFactoryBase import play.api.cache.redis._ diff --git a/src/test/scala/play/api/cache/redis/impl/BuildersSpec.scala b/src/test/scala/play/api/cache/redis/impl/BuildersSpec.scala index df5b8cf0..44b6e3de 100644 --- a/src/test/scala/play/api/cache/redis/impl/BuildersSpec.scala +++ b/src/test/scala/play/api/cache/redis/impl/BuildersSpec.scala @@ -1,6 +1,5 @@ package play.api.cache.redis.impl -import akka.pattern.AskTimeoutException import play.api.cache.redis._ import play.api.cache.redis.test._ @@ -106,12 +105,6 @@ class BuildersSpec extends AsyncUnitSpec with RedisRuntimeMock { SynchronousBuilder.toResult(Task.infinite(), Task.resolved()) mustEqual Task.resolved.response } - "recover from akka ask timeout" in { - implicit val runtime: RedisRuntime = redisRuntime(recoveryPolicy = recoveryPolicy.default) - 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 diff --git a/src/test/scala/play/api/cache/redis/impl/RedisRuntimeMock.scala b/src/test/scala/play/api/cache/redis/impl/RedisRuntimeMock.scala index 4f44ac39..e9f33b85 100644 --- a/src/test/scala/play/api/cache/redis/impl/RedisRuntimeMock.scala +++ b/src/test/scala/play/api/cache/redis/impl/RedisRuntimeMock.scala @@ -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} diff --git a/src/test/scala/play/api/cache/redis/impl/RedisRuntimeSpec.scala b/src/test/scala/play/api/cache/redis/impl/RedisRuntimeSpec.scala index 8a902088..abcfc9ff 100644 --- a/src/test/scala/play/api/cache/redis/impl/RedisRuntimeSpec.scala +++ b/src/test/scala/play/api/cache/redis/impl/RedisRuntimeSpec.scala @@ -1,7 +1,7 @@ package play.api.cache.redis.impl -import akka.actor.ActorSystem -import akka.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 diff --git a/src/test/scala/play/api/cache/redis/test/BaseSpec.scala b/src/test/scala/play/api/cache/redis/test/BaseSpec.scala index 00d7e189..cac81cb4 100644 --- a/src/test/scala/play/api/cache/redis/test/BaseSpec.scala +++ b/src/test/scala/play/api/cache/redis/test/BaseSpec.scala @@ -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._ @@ -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", diff --git a/src/test/scala/play/api/cache/redis/test/FakeApplication.scala b/src/test/scala/play/api/cache/redis/test/FakeApplication.scala index 7836ce72..d00c6be9 100644 --- a/src/test/scala/play/api/cache/redis/test/FakeApplication.scala +++ b/src/test/scala/play/api/cache/redis/test/FakeApplication.scala @@ -1,6 +1,6 @@ package play.api.cache.redis.test -import akka.actor.ActorSystem +import org.apache.pekko.actor.ActorSystem import play.api.inject.Injector trait FakeApplication extends StoppableApplication { diff --git a/src/test/scala/play/api/cache/redis/test/RedisLogger.scala b/src/test/scala/play/api/cache/redis/test/RedisLogger.scala index 1af106da..c9805837 100644 --- a/src/test/scala/play/api/cache/redis/test/RedisLogger.scala +++ b/src/test/scala/play/api/cache/redis/test/RedisLogger.scala @@ -1,11 +1,11 @@ package play.api.cache.redis.test -import akka.event.Logging.{InitializeLogger, LoggerInitialized} -import akka.event.slf4j.Slf4jLogger +import org.apache.pekko.event.Logging.{InitializeLogger, LoggerInitialized} +import org.apache.pekko.event.slf4j.Slf4jLogger /** * This logger fixes initialization issues; it fixes race conditions between - * Akka and Slf4j, this ensures that Slf4j is initialized first. + * Pekko and Slf4j, this ensures that Slf4j is initialized first. */ class RedisLogger extends Slf4jLogger { diff --git a/src/test/scala/play/api/cache/redis/test/StoppableApplication.scala b/src/test/scala/play/api/cache/redis/test/StoppableApplication.scala index 5fbd2f58..827ad810 100644 --- a/src/test/scala/play/api/cache/redis/test/StoppableApplication.scala +++ b/src/test/scala/play/api/cache/redis/test/StoppableApplication.scala @@ -1,7 +1,7 @@ package play.api.cache.redis.test -import akka.Done -import akka.actor.{ActorSystem, CoordinatedShutdown} +import org.apache.pekko.Done +import org.apache.pekko.actor.{ActorSystem, CoordinatedShutdown} import org.scalatest.Assertion import play.api.inject.ApplicationLifecycle