简体   繁体   中英

Why is this Scala Akka code does not compile?

I'm getting this compilation error which I do not understand:

[error] /Users/nicu/mooc-reactive/akkahttp-typed-actors-cluster-ORMap-followers/src/main/scala/followers/HttpServer.scala:43:76: type mismatch;
[error]  found   : akka.actor.typed.ActorRef[Res] => Req
[error]     (which expands to)  akka.actor.typed.ActorRef[scala.collection.immutable.Map[followers.UserId,followers.User]] => followers.FollowCommand
[error]  required: akka.actor.typed.ActorRef[Res] => Map[followers.UserId,followers.User]
[error]     (which expands to)  akka.actor.typed.ActorRef[scala.collection.immutable.Map[followers.UserId,followers.User]] => Map[followers.UserId,followers.User]
[error]             val usersStateFuture: Future[Res] = followersActorRef.ask[Res](func)

In my mind, this signature:

def ask[Res](replyTo: ActorRef[Res] => Req)(implicit timeout: Timeout, scheduler: Scheduler): Future[Res]  

should simply mean that a temporary actor will be created, of type ActorRef[Res], and the replyTo function can be used to create the message to the destination actor in a way that includes the reply reference to the temporary actor, which will then upon receive complete a promise thus the returned future will be completed with Res. In my case the message (Req) is a Command, more precisely the FollowCommand, while the answer (Res) is a Map[UserId, User] with the current state that the destination actor manages.

I cannot simply understand why it is not compiling, Thanks.

package followers

import akka.Done
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.scaladsl.adapter._
import akka.actor.typed.{ActorRef, ActorSystem, Behavior, Scheduler}
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.directives.PathDirectives._
import akka.util.Timeout

import scala.concurrent.Future

object HttpServer {
  val guardianBehavior: Behavior[Done] = Behaviors.setup[Done](context => {
    val followersGraphActorRef = context.spawn(FollowersData.defaultBehavior(Map()), "followersGraph")
    context.watch(followersGraphActorRef)
    Http()(context.system.toClassic).bindAndHandle(route(followersGraphActorRef), "localhost", 8080)
    Behaviors.receiveMessage {
      case Done => Behaviors.stopped
    }
  })
  val system: ActorSystem[Done] = ActorSystem[Done](guardianBehavior, "demo-system")

  def route(followersActorRef: ActorRef[Map[UserId, User]]): Route =
    pathPrefix("root") {
      import akka.http.scaladsl.server.Directives._
      import akka.http.scaladsl.server.directives.MethodDirectives.get
      import akka.http.scaladsl.server.directives.PathDirectives.path
      import akka.http.scaladsl.server.directives.RouteDirectives.complete
      concat(
        pathEnd {
          get {
            import akka.actor.typed.scaladsl.AskPattern._
            import scala.concurrent.duration._
            implicit val timeout: Timeout = Timeout(5.seconds) // usually we'd obtain the timeout from the system's configuration
            implicit val scheduler: Scheduler = system.scheduler
            type Res = Map[UserId, User]
            type Req = FollowCommand
            val func: ActorRef[Res] => Req = (replyTo: ActorRef[Map[UserId, User]]) =>  FollowCommand(UserId(1), UserId(2), replyTo)

//            def ask[Res](replyTo: ActorRef[Res] => Req)(implicit timeout: Timeout, scheduler: Scheduler): Future[Res] = {
            val usersStateFuture: Future[Res] = followersActorRef.ask[Res](func)
            onSuccess(usersStateFuture)(usersState =>
              complete(usersState.toString)) //todo json
          }
        }
        //        path(Segment) {
        //          case "segment1" =>
        //        }
      )
    }


}

The cause was the type of the actor onto which I was calling ask. That actor, after fixing, is of type ActorRef[Req] of course. The actors have the request in their type (what types of messages they can receive). Previously it was in the code above ActorRef[Response].

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM