zio / zio-actors

A high-performance, purely-functional library for building, composing, and supervising typed actors based on ZIO
https://zio.dev/zio-actors
Apache License 2.0
268 stars 56 forks source link

Add support for user defined message serialization #154

Open TobiasPfeifer opened 4 years ago

TobiasPfeifer commented 4 years ago

Java object serialization isn't a good default for message serialization. Users should be able to provide their own serializer and deserializer for their messages.

@mtsokol Can you help come up with a way to implement this?

I see two ways of doing it:

  1. Option to pass a user defined Serialization[Envelope] to an ActorSystem. The problem I have is that Command message type is any and the response A must be wrapped in an Envelope as well when send over the wire.
  2. Pass a Serialization[F[A], A] each time creating an Actor[F[A]] that can serialize and deserialize the DSL for this Actor
  3. maybe some other approach
mtsokol commented 4 years ago

@TobiasPfeifer Hi, thanks for creating issue for that and ideas! At the moment I don't know with what should we go - let's start with some research. Let's start with inspecting Akka's docs and internals, I think we could follow their approach for managing serialization, e.g. with Jackson.

There's also a project within ZIO ecosystem (https://github.com/zio/zio-codec) that in the future will address issue of serialization. But for now we can try to do our serialization with e.g. Jackson as mentioned.

Yup, internally messages are sent as Any in an Envelope, we need to inspect how is done in Akka. Then we can decide our approach based on some conclusions. WDYT?

Feel free to start and share your findings, I will also try to spend some time on it next week 🙂

TobiasPfeifer commented 4 years ago

I don't like the 'akka approach': serialization has to be provided by configuration and there is no way to utilize a more type safe approach.

I would argue for a more generic approach and use the 'akka approach' as default implementation:

given the trait

trait Serialization[T]{
  def objFromByteArray(bytes: Array[Byte]): Task[T]
  def objToByteArray(obj: T): Task[Array[Byte]]
}

on actor creation a Serialization[A] implementation should be passed to the actor instance that is used to write/read to/from bytes. Default should be provided by the ActorSystem

for creating an ActorSystem there should be an option to pass a SerializationConfig => Serialization[Any]. Default could be the akka approach that falls back to Jackson cbor or json.

mtsokol commented 4 years ago

@TobiasPfeifer Thanks for working on this. Sorry I haven't looked at it yet due to the lack of time.

OK, so as I understand you think of passing a Serializator to each actor on creation?

actor <- system.make("actor1", Supervisor.none, state, stateful, serializer)

to make it type safe? And if it's not present then fallback to unsafe default one defined by ActorSystem?

akilegaspi commented 4 years ago

Why don't we provide a well-defined Environment in the Actor System? Since Environments are extensible in ZIO; the developers themselves could provide their own implementation for the Environment that zio-actors require innately.