All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.liftweb.http.LAFutureWithSession.scala Maven / Gradle / Ivy

The newest version!
package net.liftweb.http

import net.liftweb.actor.{LAFuture, LAScheduler}
import net.liftweb.common.{EmptyBox, Failure, Full}


object LAFutureWithSession {

  /**
    * Creates `LAFuture` instance aware of the current request and session. Each `LAFuture` returned by chained
    * transformation method (e.g. `map`, `flatMap`) will be also request/session-aware. However, it's
    * important to bear in mind that initial session or request are not propagated to chained methods. It's required
    * that current execution thread for chained method has request or session available in scope if reading/writing
    * some data to it as a part of chained method execution.
    */
  def withCurrentSession[T](task: => T, scheduler: LAScheduler = LAScheduler): LAFuture[T] = {
    S.session match {
      case Full(session) =>
        withSession(task, scheduler)

      case empty: EmptyBox =>
        withFailure(empty ?~! "LiftSession not available in this thread context", scheduler)
    }
  }

  private[this] def withSession[T](task: => T, scheduler: LAScheduler): LAFuture[T] = {
    val sessionContext = new LAFuture.Context {

      def around[S](fn: () => S): () => S = {
        val session = S.session openOrThrowException "LiftSession not available in this thread context"
        session.buildDeferredFunction(fn)
      }

      def around[A, S](fn: (A) => S): (A) => S = {
        val session = S.session openOrThrowException "LiftSession not available in this thread context"
        session.buildDeferredFunction(fn)
      }
    }

    LAFuture.build(task, scheduler, Full(sessionContext))
  }

  private[this] def withFailure[T](failure: Failure, scheduler: LAScheduler): LAFuture[T] = {
    val future = new LAFuture[T](scheduler)
    future.complete(failure)
    future
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy