Akka actor serialization binding: pattern match or use package name for classes


(Ikrom) #1

I have multiple classes and I want to specify serialization binding for them. I’m going to persist them in akka persistence cassandra. Now I’m doing like this:

  actor {
    serializers {
      kryo = "com.romix.akka.serialization.kryo.KryoSerializer"
      protobuf = "akka.remote.serialization.ProtobufSerializer"
    }
    serialization-bindings {
      "java.io.Serializable" = kryo
      "com.test.category.Klass1" = protobuf
       "com.test.category.Klass2" = protobuf
       "com.test.category.Klass3" = protobuf
       "com.test.category.Klass4" = protobuf
     ....

Is it possible to optimize this with pattern matching or specifying package name? Something like one of these:

 "com.test.category._" = protobuf
 "com.test.category.*" = protobuf

(Johan Andrén) #2

No, no wildcards, but if you can introduce your own common supertype, marker trait/interface, and bind the serializer for that (like what you do with the first line with Serializable and kryo, which would use kryo for any Java serializable unless there is a more specific serializer).

I’m not sure that specific serializer, the akka.remote.serialization.ProtobufSerializer, is meant for user consumption though, even if it is not explicitly documented as internal. I’d recommend using your own type and serializer invoking protobuf rather than counting on being able to use that. But maybe you were just showing it as an example?


(Ikrom) #3

@johanandren Thanks for response.
I’m not sure how can I introduce my own common supertype with my current approach.
I wanted to use protobuf with scalapb. This comment https://github.com/scalapb/ScalaPB/issues/27#issuecomment-254684120 suggested to use protobuf with akka.


(Johan Andrén) #4

There are some issues around that, one is the amount of bytes it will take to always pass the full classname as manifest, and the other is that it will stop you from being able to do rolling upgrades since a change to the class name or the package it is in will lead to serialized data from a node with one version not being deserializable on a node with another version.

When we use protobuf for internal messages in Akka we always encode those with a string manifest based serializer instead, that manifest can be a single character and is decoupled from the class name of the thing being serialized. See for example: https://github.com/akka/akka/blob/482eaea12288e847c1cc497868ad42168dc4a316/akka-remote/src/main/scala/akka/remote/serialization/MiscMessageSerializer.scala#L343

If you don’t care about those shortcomings, or think convenience is more important, I guess it is fine to use that serializer.

For the original binding many classes without having to list them all I’d expect all the classes you generate with ScalaPB will extend some common trait, com.trueaccord.scalapb.GeneratedMessage seems to be mentioned in that specific comment thread that you referenced (I haven’t verified that). Given that is true, you should be able to bind the serializer to that trait.