2016-03-25 16 views
0

私は以下に定義する以下のアクターを持っています。Akkaの俳優はいつもタイムアウトを待っています

object AuthenticationActor { 
    def props = Props[AuthenticationActor] 

    case class LoginUser(id: UUID) 
} 

class AuthenticationActor @Inject()(cache: CacheApi, userService: UserService) extends Actor{ 
    import AuthenticationActor._ 

    def receive = { 
    case LoginEmployee(id: UUID) => { 
     userService.getUserById(id).foreach { 
     case Some(e) => { 
      println("Logged user in") 
      val sessionId = UUID.randomUUID() 
      cache.set(sessionId.toString, e) 
      sender() ! Some(e, sessionId) 
     } 
     case None => println("No user was found") 
     } 
    } 
    } 
} 

注:

class EmployeeController @Inject()(@Named("authentication-actor") authActor: ActorRef)(implicit ec: ExecutionContext) extends Controller { 

    override implicit val timeout: Timeout = 5.seconds 

    def login(id: UUID) = Action.async { implicit request => 
    (authActor ? LoginUser(id)).mapTo[Option[(User, UUID)]].map { 
     case Some(authInfo) => Ok("Authenticated").withSession(request.session + ("auth" -> authInfo._2.toString)) 
     case None => Forbidden("Not Authenticated") 
    } 
    } 
} 

それにFuture[Option[User]]

そして、次の非常に単純なAPIのCALを返しuserService.getUserByIdどちらprintln呼び出しが実行されますが、login呼び出しは常に尋ねるが持っていると言って失敗しますタイムアウト。助言がありますか?

+0

あなたは私がmapTo O/pipeToを使用してはならないとのFuture結果ですか? – Ashalynd

答えて

3

あなたがそのようなこと(Futureのコールバック内の送信者へのアクセス)を行うと、それはFuture完了する前に、非常に可能性の高い変更であるので、あなたがあなたが要求を受信したときにoutterスコープでvalsenderを保存する必要があります。

def receive = { 
    case LoginEmployee(id: UUID) => { 
     val recipient = sender 

     userService.getUserById(id).foreach { 
     case Some(e) => { 
      ... 
      recipient ! Some(e, sessionId) 
     } 
     ... 
     } 
    } 
    } 

ユーザーが見つからなかった場合は決して結果を送信しません。あなたが実際にここに何をすべき

はパイプがsender

def receive = { 
    case LoginEmployee(id: UUID) => { 
    userService.getUserById(id) map { _.map { e => 
     val sessionId = UUID.randomUUID() 
     cache.set(sessionId.toString, e) 
     (e, sessionId) 
     } 
    } pipeTo sender 
    } 
} 

またはプリント

def receive = { 
    case LoginEmployee(id: UUID) => { 
    userService.getUserById(id) map { 
     case Some(e) => 
     println("logged user in") 
     val sessionId = UUID.randomUUID() 
     cache.set(sessionId.toString, e) 
     Some(e, sessionId) 
     case None => 
     println("user not found") 
     None 
    } pipeTo sender 
    } 
} 
+0

最初の例では、 'val recipient = sender'は' val recipient = sender() 'でなければなりません(括弧に注意してください)。 – russianmario

+0

Scalaでは、0アリティメソッドの括弧を省略することができます。http://docs.scala-lang.org/style/method-invocation.html –

+0

私の謝罪 - 私はちょうどどこかが悪いと読みましたこれを行うには練習する(または間違っている)が、私はもはや参照を見つけることができない。間違っていなければなりません。 – russianmario

関連する問題