I am re-learning Scala, and I wanted to do a system flow as follows
Routes(Akka-Http) which asks an Actor Model(Akka) which then asks the Database through a Slick Model.
Something like
Route
path("rooms"){
get {
val rooms = (actorRoom ? GetRooms).mapTo[Seq[Room]] //bad code
complete(rooms) //bad code
}
}
ActorRoom
def receive = {
case GetRooms => sender() ! ModelRoom.getRooms()
Slick Model
val rooms = TableQuery[RoomTable]
def getRooms(): Future[Seq[Room]] = rooms.result
My problem is that i am not sure when to resolve the rooms.
Should I do it within the actor? (the route complete does not seem to wait)
Should I do it within the route? (how should i do it?)
Is this approach correct, or the actor is too much?
Adding an Actor in the flow when your DB call itself is asynchronous can be dangerous since it can lead to un-predictable results.
But if you ignore all the unpredictability and still want to do it, you can make it work like this,
your route,
import akka.pattern.ask
import akka.actor.Status
import scala.util.{Success, Failure}
path("rooms"){
get {
val dbCallThroughActor = (actorRoom ? GetRooms).map({
case Status.Success(seq) => seq
case Status.Failure(ex) => throw ex
})
onComplete(dbCallThroughActor.mapTo[Seq[Room]]) {
case Success(seq) => complete(seq)
// or your can reject with your rejection handler
case Failure(ex) => complete(ex)
}
}
}
your actor,
import context.dispatcher
def receive = {
case GetRooms =>
ModelRoom.getRooms().pipeTo(sender())
}
your slick model,
val rooms = TableQuery[RoomTable]
def getRooms()(implicit ec: ExecutionContext): Future[Seq[Room]] = database.run(rooms.result)
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.