Skip to content

Commit

Permalink
support rollback from pekko migration
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendan Doyle authored and scullxbones committed Sep 24, 2023
1 parent 0bace14 commit 9fac485
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

* Test suite verifies against MongoDB 3.6, 4.0, 4.2

### Preparing to migrate to Apache Pekko? Use 4.x Series.

* Provides forwards compatibility for Akka / Pekko features that persist internal class names, allowing for you to safely roll back your application after migration.

### Using Akka 2.6? Use 3.x Series.
[![Build Status](https://travis-ci.com/scullxbones/akka-persistence-mongo.svg?branch=master)](https://travis-ci.org/scullxbones/akka-persistence-mongo)
![Maven Central 2.12](https://maven-badges.herokuapp.com/maven-central/com.github.scullxbones/akka-persistence-mongo-common_2.12/badge.svg)
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
val releaseV = "3.0.8"
val releaseV = "4.0.0"

val scala212V = "2.12.15"
val scala213V = "2.13.7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import akka.actor.ActorRef
import akka.persistence.journal.Tagged
import akka.persistence.query.{EventEnvelope, Offset}
import akka.persistence.{AtomicWrite, PersistentRepr}
import akka.serialization.{Serialization, SerializerWithStringManifest}
import akka.serialization.{Serialization, Serializer, SerializerWithStringManifest}

import scala.collection.immutable.{Seq => ISeq}
import scala.language.existentials
Expand Down Expand Up @@ -51,15 +51,28 @@ case class Serialized[C <: AnyRef](bytes: Array[Byte],
lazy val content: C = {

val clazz = loadClass.getClassFor[X forSome { type X <: AnyRef }](className)
Try(tryDeserialize(clazz, clazz.flatMap(c => Try(ser.serializerFor(c)))))
.recover({
case _ if className.startsWith("org.apache.pekko.") =>
val backwardsCompatClazz = loadClass.getClassFor[X forSome { type X <: AnyRef }](className.replaceFirst("org.apache.pekko", "akka"))
tryDeserialize(backwardsCompatClazz, backwardsCompatClazz.flatMap(c => Try(ser.serializerFor(c))))
case x => throw x
}) match {
case Failure(x) => throw x
case Success(deser) => deser
}
}

val tried = (serializedManifest,serializerId,clazz.flatMap(c => Try(ser.serializerFor(c)))) match {
private def tryDeserialize(clazz: Try[Class[_ <: X forSome {type X <: AnyRef}]],
serializer: Try[Serializer]): C = {
val tried = (serializedManifest, serializerId, serializer) match {
// Manifest was serialized, class exists ~ prefer read-time configuration
case (Some(manifest), _, Success(clazzSer)) =>
ser.deserialize(bytes, clazzSer.identifier, manifest)

// No manifest id serialized, prefer read-time configuration
case (None, _, Success(clazzSer)) =>
ser.deserialize[X forSome { type X <: AnyRef }](bytes, clazzSer.identifier, clazz.toOption)
ser.deserialize[X forSome {type X <: AnyRef}](bytes, clazzSer.identifier, clazz.toOption)

// Manifest, id were serialized, class doesn't exist - use write-time configuration
case (Some(manifest), Some(id), Failure(_)) =>
Expand Down

0 comments on commit 9fac485

Please sign in to comment.