Akka HTTP + actor + slick postgresql

时间:2017-02-17 19:03:50

标签: scala architecture akka slick akka-http

我正在重新学习Scala,我想按照以下方式进行系统流程

路线(Akka-Http),它询问一个演员模型(Akka),然后通过光滑模型询问数据库。

这样的东西

路线

path("rooms"){
  get {
    val rooms = (actorRoom ? GetRooms).mapTo[Seq[Room]] //bad code
    complete(rooms) //bad code
  }
}

ActorRoom

def receive = {
  case GetRooms => sender() ! ModelRoom.getRooms()

光滑模型

val rooms = TableQuery[RoomTable]
def getRooms(): Future[Seq[Room]] = rooms.result

我的问题是我不确定何时解决房间。

我应该在演员中做到吗? (路线完整似乎不等待)

我应该在路线内做吗? (我该怎么做?)

这种方法是否正确,还是演员太多了?

1 个答案:

答案 0 :(得分:3)

当您的数据库调用本身是异步时,在流中添加一个Actor可能很危险,因为它可能导致无法预测的结果。

但是如果你忽略了所有的不可预测性并仍然想要这样做,你可以让它像这样工作,

你的路线,

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)
    }
  }
}

你的演员,

import context.dispatcher

def receive = {
  case GetRooms =>
    ModelRoom.getRooms().pipeTo(sender())
}

光滑的模型,

val rooms = TableQuery[RoomTable]
def getRooms()(implicit ec: ExecutionContext): Future[Seq[Room]] = database.run(rooms.result)