Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to enrich a command as well as an event #74

Open
guersam opened this issue Jun 25, 2019 · 4 comments
Open

Allow to enrich a command as well as an event #74

guersam opened this issue Jun 25, 2019 · 4 comments

Comments

@guersam
Copy link
Contributor

guersam commented Jun 25, 2019

It would be nice if I could attach some metadata such as the correlation id to a command so that it can be merged into the metadata of the corresponding events.

There are already pure equivalents of Java's ThreadLocal such as monix.eval.TaskLocal and zio.FiberRef that can propagate its local state through the effect context.

A possible use case:

  1. A http4s middleware generates a correlation id, and embeds it in the fiber (effect context) using TaskLocal/FiberRef
  2. The Aecor runtime serializes and sends the command using an enriched wire protocol that extracts the correlation id and makes command metadata
  3. The corresponding command handler deserializes the command and embeds the metadata in the fiber
  4. The enriched event handler extracts the metadata from the fiber and put the correlation id into the event metadata

Reference: https://blog.softwaremill.com/correlation-ids-in-scala-using-monix-3aa11783db81

@notxcain
Copy link
Owner

notxcain commented Jun 25, 2019

Good idea.

I think it is doable using a trick similar to EitherK[M, R, F]. It turns M[F] into M[EitherT[F, R, ?]].

You can create EnrichedK[M, C, F] that turns your M[F] into M[ReaderT[F, C, ?]].

@guersam
Copy link
Contributor Author

guersam commented Jun 25, 2019

That's another possible interpretation.

Basically I prefer MTL style typeclass with effect-native interpretation over traditional monad transformer, for example, MonadState[IO, S] with Ref[IO, S] over StateT[IO, S, ?].

Speaking of the Akka cluster runtime, the tricky part seems to me is steps 2 and 3 in the above use case. Regardless of the effect stack, the wire protocol should encode the command and metadata something like Enriched[Metadata, Command] into binary, and then it's GenericAkkaRuntimeActor's responsibility to unwrap the command for the behavior function and to construct the effect stack again, possibly setting TaskLocal/FiberRef by itself with metadata.

InvariantK pops up in my head...

@typeclass trait InvariantK[A[_[_]]] {
  def imapK[F[_], G[_]](af: A[F])(fk: F ~> G)(gK: G ~> F): A[G]
}

@notxcain
Copy link
Owner

I see what you want however I prefer to use composition rather than modify existing runtime. So I need some time to think about it :)

@guersam
Copy link
Contributor Author

guersam commented Jun 25, 2019

I understand that you want to avoid changes in the runtime because you're already running Aecor based services in production. Please feel free to take your time and let me know your thoughts :) I'll add my findings as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants