I'm new to scala and have been working to understand the syntax so that I can be more efficient. How does this look in terms of functional syntax and scala idioms?
In particular, I'd like to know if this is a good way of handling futures. I'm aware of onComplete, onSuccess, etc..., matching but I had trouble getting a return value back out. map seemed like the right approach here.
object Application extends Controller with securesocial.core.SecureSocial {
val inboxSlurper = Akka.system.actorOf(Props[InboxSlurper], name = "inboxSlurper")
def index = SecuredAction.async {
implicit request =>
implicit val timeout = Timeout(10 seconds)
val user: User = request.user.asInstanceOf[User]
val f = inboxSlurper.ask(
OauthIdentity(
user.email.get,
user.oAuth2Info.get.accessToken))
f flatMap { reply =>
val emailFeed = reply.asInstanceOf[Enumerator[Message]]
val iter = Iteratee.fold[Message, String]("")((result, msg) => result + msg.getSubject())
emailFeed |>>> iter
} map { str =>
Logger.debug(str);
val subj = "Subject: %s".format(str)
Ok(views.html.index(subj))
}
}
}
1 Answer 1
Future "callbacks" can be simplified by using the for
comprehension to compose futures. More information can be found here http://docs.scala-lang.org/overviews/core/futures.html#functional_composition_and_forcomprehensions
I'm not a Scala expert, but this is how i would replace the flatMap and map with a for
object Application extends Controller with securesocial.core.SecureSocial {
val inboxSlurper = Akka.system.actorOf(Props[InboxSlurper], name = "inboxSlurper")
def index = SecuredAction.async { implicit request =>
implicit val timeout = Timeout(10 seconds)
val user = request.user.asInstanceOf[User]
for {
emailFeed <- (inboxSlurper ? OauthIdentity(user.email.get, user.oAuth2Info.get.accessToken))).mapTo[Enumerator[Message]]
str <- emailFeed |>>> Iteratee.fold[Message, String]("")((result, msg) => result + msg.getSubject())
} yield Ok(views.html.index("Subject: %s".format(str)))
}
}
The example demonstrates the sequential composition of futures, str will be calculated when emailFeed has retrieved the data for the inboxSlurper actor. After all futures have been completed then a result can be returned with yield
.
Because everything is a expression in Scala for {} yield Ok()
will be returned as result for the Action, which is a Future[SimpleResult].