VirtusLab / akka-serialization-helper

Serialization toolbox for Akka messages, events and persistent state that helps achieve compile-time guarantee on serializability. No more errors in the runtime!
MIT License
26 stars 5 forks source link

Add support for Akka classic in dumping persistence schema #125

Open PawelLipski opened 3 years ago

LukaszKontowski commented 2 years ago

Current solution for akka-typed:

/**
       * All these types have three things in common:
       *   - they have 2 or more type parameters
       *   - the last type parameter corresponds to state type
       *   - the last but one type parameter corresponds to event type
       */
      private val genericsNames =
        Seq(
          "akka.persistence.typed.scaladsl.Effect",
          "akka.persistence.typed.scaladsl.EffectBuilder",
          "akka.persistence.typed.scaladsl.EventSourcedBehavior",
          "akka.persistence.typed.scaladsl.ReplyEffect")

Is based on code occurences of Event and State type parameters (where "Event" and "State" are not real existing types but just meaningful names) - that's how these four types were chosen. That's how we know that these particular types from akka-persistence-typed are releated to persistent events and states.

In case of akka-classic - we cannot do a similar thing - as "State" and "Event" keywords are not used as type parameters. In fact, if there are type parameters - there are two options:

So, from a quick research on the akka-persistence (classic) code base, here are my "candidates" for types that might be used:

      akka.persistence.state.scaladsl.DurableStateStore
      akka.persistence.state.scaladsl.DurableStateUpdateStore
      akka.persistence.journal.EventAdapter
      akka.persistence.journal.WriteEventAdapter
      akka.persistence.journal.ReadEventAdapter
      akka.persistence.Persistence
      akka.persistence.PersistentActor
      akka.persistence.journal.inmem.InmemJournal.Write
      akka.persistence.journal.inmem.InmemJournal.Delete

However, this is not a full list and research is not completed. @PawelLipski - what is your opinion on this? Or maybe you have some better idea?

PawelLipski commented 2 years ago

Huh okay, before you start further work here (as the effort/benefit ratio might not be the best for this issue)...

"candidates" for types that might be used

By used, you mean that you would detect all the types that extend any of these types and consider them to be persisted types whose schemas needs to be dumped? 🤔 Best if you could provide some small sandbox-like example here of a class and its corresponding dump in the comments

LukaszKontowski commented 2 years ago

By used, you mean that you would detect all the types that extend any of these types and consider them to be persisted types whose schemas needs to be dumped?

No, current logic for typed "candidates" (genericsNames - fqcns for typed):

val foundUsedClasses: List[(Type, Position)] = body.collect {
  case x: TypeTree if genericsNames.contains(x.tpe.dealias.typeSymbol.fullName) =>
    x.tpe.typeArgs.takeRight(2).map((_, x.pos))
  }.flatten

So - from current source file we collect all usages of types from genericsNames. And these usages mean that in this place we persist some Events / States.

My idea is to find "candidates" (fqcns) for akka classic - types that can be used to persist Events / States. It would be nice to find a repo that still uses akka classic for persistence to check, which types from classic are in fact used to do this.