スプレー akka を使用してオブジェクトを Json にアンマーシャリングすることに問題があります。
Future[List[Person]] を返すアクターを使用したいのですが、うまくいきません。
dao オブジェクトを直接使用すると機能します。
ここに私のコードがあります:
PersonDao.scala
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
case class Person(id: Int, name: String, surname: String)
object PersonDao {
def getAll: Future[List[Person]] = Future {
List[Person](Person(1, "Bilal", "Alp"), Person(2, "Ahmet", "Alp"))
}
}
EntityServiceActor.scala
import akka.actor.Actor
import com.bilalalp.akkakafka.model.PersonDao
import com.bilalalp.akkakafka.service.ServiceOperation.FIND_ALL
object ServiceOperation {
case object FIND_ALL
}
class EntityServiceActor extends Actor {
override def receive: Receive = {
case FIND_ALL => PersonDao.getAll
}
}
ServerSupervisor.scala
import akka.actor.{Actor, ActorRefFactory}
import com.bilalalp.akkakafka.webservice.TaskWebService
import spray.routing.RejectionHandler.Default
class ServerSupervisor extends Actor with PersonWebService {
implicit val system = context.system
override def receive: Receive = runRoute(entityServiceRoutes)
override implicit def actorRefFactory: ActorRefFactory = context
}
WebServiceTrait.scala
import akka.util.Timeout
import spray.routing.HttpService
import scala.concurrent.duration._
import scala.language.postfixOps
import org.json4s.NoTypeHints
import org.json4s.native.Serialization._
trait WebServiceTrait extends HttpService {
implicit def executionContext = actorRefFactory.dispatcher
implicit val json4sFormats = formats(NoTypeHints)
implicit val timeout = Timeout(120 seconds)
}
PersonWebService.scala
trait PersonWebService extends WebServiceTrait with Json4sSupport {
val json3sFormats = DefaultFormats
val entityServiceWorker = actorRefFactory.actorOf(Props[EntityServiceActor], "entityServiceActor")
val entityServiceRoutes = {
pathPrefix("person") {
pathEndOrSingleSlash {
get {
ctx => ctx.complete((entityServiceWorker ? FIND_ALL).mapTo[Person])
}
}
}
}
}
アプリケーション.scala
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.io.IO
import com.bilalalp.akkakafka.server.ServerSupervisor
import spray.can.Http
object Application extends App {
implicit val system = ActorSystem("actorSystem")
val mainHandler: ActorRef = system.actorOf(Props[ServerSupervisor])
IO(Http)! Http.Bind(mainHandler, interface = Configuration.appInterface, port = Configuration.appPort)
}
このコードを実行すると、何も表示されず、しばらく待ちます。
ブラウザを待った後、次のメッセージが表示されます。
サーバーは、要求に対してタイムリーな応答を生成できませんでした。
そしてコンソール出力は
[エラー] [11/22/2015 21:15:24.109] [actorSystem-akka.actor.default-dispatcher-7] [akka.actor.ActorSystemImpl(actorSystem)] リクエスト HttpRequest(GET, http:/ /localhost:3001/person/,List(ホスト: localhost:3001、接続: キープアライブ、キャッシュ制御: キャッシュなし、プラグマ: キャッシュなし、ユーザーエージェント: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML、Gecko など) Maxthon /4.4.6.1000 Chrome/30.0.1599.101 Safari/537.36、DNT: 1、Accept-Encoding: gzip、deflate、Accept-Language: tr-TR)、Empty、HTTP/1.1) akka.pattern.AskTimeoutException: タイムアウトを要求する[Actor[akka://actorSystem/user/$a/entityServiceActor#-1810673919]] [120000 ミリ秒] 後。Sender[null] は、タイプ「com.bilalalp.akkakafka.service.ServiceOperation$FIND_ALL$」のメッセージを送信しました。akka.pattern.PromiseActorRef$$anonfun$1.apply$mcV$sp(AskSupport.scala:415) akka.actor.Scheduler$$anon$7.run(Scheduler.scala:132) scala.concurrent.Future$InternalCallbackExecutor $.unbatchedExecute(Future.scala:599) を scala.concurrent で。
PersonWebService.scala をこれに変更すると:
trait PersonWebService extends WebServiceTrait with Json4sSupport {
val json3sFormats = DefaultFormats
val entityServiceWorker = actorRefFactory.actorOf(Props[EntityServiceActor], "entityServiceActor")
val entityServiceRoutes = {
pathPrefix("person") {
pathEndOrSingleSlash {
get (
// ctx => ctx.complete((entityServiceWorker ? FIND_ALL).mapTo[Person])
ctx => ctx.complete(PersonDao getAll)
)
}
}
}
}
それは動作し、出力は次のとおりです。
[{"id":1,"name":"Bilal","surname":"Alp"},{"id":2,"name":"Ahmet","surname":"Alp"}]
スプレー ルートでアクターを使用したいと思います。私はakkaとsprayの初心者なので、それが悪い習慣なのかどうかはわかりません。
どうすればこれを解決できますか? 何か案は?
ありがとうございました。