Accessing S params and other internals inside RestContinuations.

32 views
Skip to first unread message

Flavian Alexandru

unread,
May 24, 2015, 12:57:30 PM5/24/15
to lif...@googlegroups.com
As heavy Lift users, we've always made it a point to adopt async patterns in all of our applications. The problem in Continuations is however somewhat strange and it seems that some crucial variables, and especially things to do with S and the underlying JSessions are either ThreadLocal or similar. The bottom line being not even request params are available inside continuations. 

To get around this, we've implemented very simple flow control. Let's address a simple use case:


import net.liftweb.http.rest.RestHelper
import com.websudos.util.lift._

import scalaz._
import scalaz.Scalaz._

object Api extends RestHelper {

  serve {
    case "api" :: "v1" :: "profile" :: id :: Nil Get _ => {
       // let's say we want an UUID
       // parse is a Scalaz parser typeclass collection defined for our convenience.
       // map is a way to map the successful parse result to a Future[LiftResponse]
       // _.asResponse() converts products to JsonResponse()
       // async is the bit that introduces the continuation 
       parse[UUID].map(uid => { Database.getProfileById(uid).map(_.asResponse())).async()
    }
  }
}


And now the implementation of async, pasted with all the fancy formatting form InteliJ

implicit class FutureResponseHelper(val responseFuture: Future[LiftResponse]) extends AnyVal {

def async(failureCode: Int = 500)(implicit context: ExecutionContext): LiftResponse = {
RestContinuation.async {
reply => {
responseFuture.onComplete {
case Success(resp) => reply(resp)
case Failure(err) => reply(err.toJson(failureCode))
}
}
}
}
}



The problem is that sometimes these inner functions need to call not only parameters but also authentication related things which don't work and other similar things. Lift introduces a lot of primitives such as LAFuture or similar, but to maintain compatibility across the board a new kind of Future doesn't seem like a good idea.

Bottom line, is there a way to correctly read S.params for instance inside a Continuation or using lift-shiro a way to read authentication status? None of these work, so on the "outer" part of a Continuation your user will be authenticated, in the inner part it will not.

Regards.



Reply all
Reply to author
Forward
0 new messages