2016-03-25 11 views
0

Aşağıdaki "" kullanıcı girişi "anlamına gelen aşağıda tanımlanan aktöre sahibim.Akka aktörleri her zaman dışarıda beklerler

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

Not: userService.getUserById bir Future[Option[User]]

Ve bunun

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

İkisi println aramalar çalıştırır aşağıdaki çok basit API cal döndürür, ancak login çağrı hep vardır sormak söyleyerek başarısız olur zaman aşımı. Baska öneri? Eğer (Future s callback'inde içinde gönderen erişim) böyle bir şey yaptığınızda

+0

i/mapTo o pipeTo kullanmamalısınız 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 } } 

veya baskılar Future sonucudur? – Ashalynd

cevap

3

Eğer isteği geldiğinde sadece Future tamamlamadan önce çok büyük olasılıkla değişiklik olduğu için outter kapsamında bir val içinde sender saklamamız gerekir.

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

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

Ayrıca, kullanıcı bulunamadığı zaman hiçbir sonuç göndermezsiniz.

Ne Aslında burada yapmalıyım boru

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

İlk örneğinizde, "val alıcısı = gönderici" nin val alıcısı = gönderici() olması gerektiğini düşünüyorum (parantezlere dikkat edin). – russianmario

+0

Scala, 0-aritme yöntemleri için parantezi çıkarmayı sağlar, bkz .: http://docs.scala-lang.org/style/method-invocation.html –

+0

Özür dilerim - Yemin edebilirim ki, bir yerlerde kötü olduğunu okudum Bunu yapmak için pratik (veya yanlış), ancak artık referansı bulamıyorum. Yanlış okumalı. – russianmario