I have application that build on akka-http and slick. All services works with slick DBIO
instances which transforms into Future
in the routes classes. Implicit parameter widely used through services to pass context about current request (user id, permissions etc.) Typical methods signature looks in following way:
def getProject(id: ProjectId)(implicit context: Context): DBIO[Project] = {???}
Everything was fine until this context was readonly. Now I have a requirement to implement domain events approach and dispatch events only after transaction commit. So I decided to store list of events in context and fire them after successfully transforming DBIO
into Future
.
My question is how properly mutate this implicit context through different service methods in functional way? I thought about using State monad transformer , but it feels that it bring more complexity cause all services already build over DBIO
.
If you consider using Cats Effect, you could use Ref to store events.
val events: F[Ref[F, List[DomainEvent]]] = Ref.of[F, List[DomainEvent]](Nil)
// assuming that you'll make F=DBIO and provide necessary type class instances
def getProject(id: ProjectId)(implicit events: Ref[DBIO, List[DomainEvents]]): DBIO[Project] = for {
... // database actions
_ <- events.update(list :+ event)
} yield ...
Then before running transaction:
for {
result <- ... // your queries, where you pass events
eventList <- events.get
} yield (result, eventList)
Ref acts like an atomic wrapper around some data and uses effect defined by you to provide some safety.
There are other options:
What you pick is a matter of preference.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.