Skip to content

Commit

Permalink
Avoid triggering side-effects for read-only commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonas Chapuis authored and jchapuis committed Dec 12, 2021
1 parent d7fe199 commit 81f93f5
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
6 changes: 5 additions & 1 deletion documentation/src/main/paradox/effector.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ trait Self[F[_], Alg[_[_]]] {
trait Effector[F[_], S] extends StateReader[F, S] with Passivator[F] with Self[F]
```

@scaladoc[Effector](endless.core.entity.Effector) is a typeclass used to describe side effects occurring **after** event persistence and entity recovery.
@scaladoc[Effector](endless.core.entity.Effector) is a typeclass used to describe side effects occurring **after** event persistence and entity recovery.

Side-effects are typically asynchronous operations such as kafka writes, outgoing REST requests, and [entity passivation](https://doc.akka.io/docs/akka/current/typed/cluster-sharding.html#passivation) (flushing out of memory). `Effector` is used in a `Effector => F[Unit]` function provided upon entity deployment (e.g. @github[BookingEffector](/example/src/main/scala/endless/example/logic/BookingEffector.scala)). In the provided Akka runtime, the resulting `F[Unit]` is executed in *run & forget* mode so that command reply is not delayed by any lengthy side-effect (`Self` can be used to notify success or failure of asynchronous operations back to the entity).

@@@ warning
In the provided Akka runtime, read-only commands (commands that do not generate events) do not trigger side-effects, which corresponds to sound practice.
@@@

@@@ note
Defining an effector is entirely optional with the Akka runtime, pass-in `(_, _) => EffectorT.unit` in @scaladoc[deployEntity](endless.runtime.akka.Deployer) to disable effector.
@@@
Expand Down
8 changes: 7 additions & 1 deletion runtime/src/main/scala/endless/runtime/akka/Deployer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ trait Deployer {
.flatMap {
case Left(error) =>
Logger[F].warn(error) >> Effect.unhandled[E, Option[S]].thenNoReply().pure
case Right((events, reply)) =>
case Right((events, reply)) if events.nonEmpty =>
Effect
.persist(events.toList)
.thenRun((state: Option[S]) =>
Expand All @@ -250,6 +250,12 @@ trait Deployer {
Reply(incomingCommand.replyEncoder.encode(reply))
}
.pure
case Right((_, reply)) =>
Effect
.reply[Reply, E, Option[S]](command.replyTo)(
Reply(incomingCommand.replyEncoder.encode(reply))
)
.pure
}
dispatcher.unsafeRunSync(effect)
}
Expand Down

0 comments on commit 81f93f5

Please sign in to comment.