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

net.liftweb.http.rest.RestContinuation.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2007-2011 WorldWide Conferencing, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.liftweb 
package http 
package rest 

import scala.collection.mutable.{HashMap, ListBuffer}
import net.liftweb.common._
import net.liftweb.actor._
import net.liftweb.util._

final private[http] case class ContinuationException(req: Req, session: Box[LiftSession], f: ((=> LiftResponse) => Unit) => Unit) extends LiftFlowOfControlException("Continuation")

/**
 * Provides a generic way of sending asynchronous response to HTTP clients. If
 * the underlying web container does not support continuations the asynchronous
 * nature is achieved using locks.
 */
object RestContinuation {

  /**
   * Process a request asynchronously.  If your web container supports
   * Async calls/Continuations (e.g., Jetty 6, Jetty 7, and Servlet 3.0
   * containers including Jetty 8 and Glassfish), the thread will not
   * block until there's a response.  The parameter is a function
   * that takes a function as it's parameter.  The function is invoked
   * when the calculation response is ready to be rendered:
   * 
   * RestContinuation.async {
   *   reply => {
   *     myActor ! DoCalc(123, answer => reply{XmlResponse({answer})})
   *   }
   * }
   *
   * class MyActor {
   *   def lowPriority = {
   *     case DoCalc(value, whenDone) => whenDone(value * 10)
   *   }
   * }
   * 
* * Alternatively, from RestHelper: *
   * serve {
   *   case "api" :: id _ Get _ => RestContinuation.async {
   *      reply => for {i <- longCalc(id)} reply({i})
   *   }
   * }
   * 
* * The body of the function will be executed on a separate thread. * When the answer is ready, apply the reply function... the function * body will be executed in the scope of the current request (the * current session and the current Req object). */ def async(f: ((=> LiftResponse) => Unit) => Unit): Nothing = { throw new ContinuationException(CurrentReq.value, S.session, f) } } object ContinuationsStore extends SessionVar[HashMap[ContinuationKey, Continuation]](new HashMap[ContinuationKey, Continuation]) trait Continuation { def tryRespond: Box[LiftResponse] } case class ContinuationKey(path: ParsePath, reqType: RequestType)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy