Permalink
Browse files

WIP for comet enhancements

  • Loading branch information...
1 parent fce621b commit f26ddf21de7ddd43339f3ae7f5e45018fc855fdd @dpp dpp committed Feb 18, 2011
@@ -1,7 +0,0 @@
-package net.liftweb.util;
-
-public interface BaseFoo {
- public void test ();
-
- public void testInt (int test);
-}
@@ -1,11 +0,0 @@
-package net.liftweb.util;
-
-public class FooTester {
- public static void test(BaseFoo foo) {
- foo.testInt(42);
- }
-
- public static void test(ComplexFoo foo) {
- foo.testString("foo!");
- }
-}
@@ -1,5 +0,0 @@
-package net.liftweb.util
-
-trait ComplexFoo extends BaseFoo {
- def testString (test : String)
-}
@@ -47,7 +47,8 @@ object Comet extends DispatchSnippet with LazyLoggable {
private def buildComet(kids: NodeSeq) : NodeSeq = {
val theType: Box[String] = S.attr.~("type").map(_.text)
val name: Box[String] = S.attr.~("name").map(_.text) orElse
- S.attr.~("metaname").map(_.text).flatMap(S.param)
+ S.attr.~("metaname").map(_.text).flatMap(S.param) orElse
+ S.attr.~("randomname").map(ignore => Helpers.nextFuncName)
(for {ctx <- S.session} yield {
@@ -61,7 +61,8 @@ object LazyLoad extends DispatchSnippet {
ret.initCometActor(session,
Full(theType),
name, defaultXml, attributes)
- ret ! PerformSetupComet
+ ret ! PerformSetupComet2(if (ret.sendInitialReq_?)
+ S.request.map(_.snapshot) else Empty)
// and save it in the request var
myActor.set(Full(ret))
@@ -411,6 +411,19 @@ trait LiftCometActor extends TypedActor[Any, Any] with ForwardableActor[Any, Any
def poke(): Unit = {}
/**
+ * Is this CometActor going to capture the initial Req
+ * object? If yes, override this method and return true
+ * and override captureInitialReq to capture the Req. Why
+ * have to explicitly ask for the Req? In order to send Req
+ * instances across threads, the Req objects must be snapshotted
+ * which is the process of reading the POST or PUT body from the
+ * HTTP request stream. We don't want to do this unless we
+ * have to, so by default the Req is not snapshotted/sent. But
+ * if you want it, you can have it.
+ */
+ def sendInitialReq_? : Boolean = false
+
+ /**
* If the predicate cell changes, the Dependent will be notified
*/
def predicateChanged(which: Cell[_]): Unit = {poke()}
@@ -791,10 +804,12 @@ trait CometActor extends LiftActor with LiftCometActor with BindHelpers {
}
- case PerformSetupComet =>
+ case PerformSetupComet2(initialReq) => {
// this ! RelinkToActorWatcher
- localSetup
+ localSetup()
+ captureInitialReq(initialReq)
performReRender(true)
+ }
/**
* Update the defaultHtml... sent in dev mode
@@ -1028,6 +1043,18 @@ trait CometActor extends LiftActor with LiftCometActor with BindHelpers {
*/
protected def localSetup(): Unit = {}
+ /**
+ * Comet Actors live outside the HTTP request/response cycle.
+ * However, it may be useful to know what Request led to the
+ * creation of the CometActor. You can override this method
+ * and capture the initial Req object. Note that keeping a reference
+ * to the Req may lead to memory retention issues if the Req contains
+ * large message bodies, etc. It's optimal to capture the path
+ * or capture any request parameters that you care about rather
+ * the keeping the whole Req reference.
+ */
+ protected def captureInitialReq(initialReq: Box[Req]) {}
+
private def _localShutdown() {
localShutdown()
clearNotices
@@ -1083,7 +1110,7 @@ trait CometActor extends LiftActor with LiftCometActor with BindHelpers {
who.callInitCometActor(theSession, Full(who.uniqueId), name, defaultHtml, attributes)
theSession.addCometActor(who)
// who.link(this)
- who ! PerformSetupComet
+ who ! PerformSetupComet2(Empty)
askingWho = Full(who)
this.answerWith = Full(answerWith)
who ! AskQuestion(what, this, listeners)
@@ -1261,7 +1288,7 @@ case class UpdateDefaultXml(xml: NodeSeq) extends CometMessage
case class PartialUpdateMsg(cmd: () => JsCmd) extends CometMessage
case object AskRender extends CometMessage
case class AnswerRender(response: XmlOrJsCmd, who: LiftCometActor, when: Long, displayAll: Boolean) extends CometMessage
-case object PerformSetupComet extends CometMessage
+case class PerformSetupComet2(initialReq: Box[Req]) extends CometMessage
case object ShutdownIfPastLifespan extends CometMessage
case class AskQuestion(what: Any, who: LiftCometActor, listeners: List[(ListenerId, AnswerRender => Unit)]) extends CometMessage
case class AnswerQuestion(what: Any, listeners: List[(ListenerId, AnswerRender => Unit)]) extends CometMessage
@@ -1898,7 +1898,8 @@ class LiftSession(private[http] val _contextPath: String, val uniqueId: String,
asyncComponents(what) = act
}
act.callInitCometActor(this, theType, name, defaultXml, attributes)
- act ! PerformSetupComet
+ act ! PerformSetupComet2(if (act.sendInitialReq_?)
+ S.request.map(_.snapshot) else Empty)
}
}
@@ -1941,9 +1942,11 @@ class LiftSession(private[http] val _contextPath: String, val uniqueId: String,
val createInfo = CometCreationInfo(contType, name, defaultXml, attributes, this)
val boxCA: Box[LiftCometActor] = LiftRules.cometCreationFactory.vend.apply(createInfo).map{
- a => a ! PerformSetupComet; a} or
+ a => a ! PerformSetupComet2(if (a.sendInitialReq_?)
+ S.request.map(_.snapshot) else Empty); a} or
LiftRules.cometCreation.toList.find(_.isDefinedAt(createInfo)).map(_.apply(createInfo)).map{
- a => a ! PerformSetupComet; a} or
+ a => a ! PerformSetupComet2(if (a.sendInitialReq_?)
+ S.request.map(_.snapshot) else Empty); a} or
(findType[LiftCometActor](contType, LiftRules.buildPackage("comet") ::: ("lift.app.comet" :: Nil)).flatMap {
cls =>
tryo((e: Throwable) => e match {
@@ -1954,13 +1957,15 @@ class LiftSession(private[http] val _contextPath: String, val uniqueId: String,
val ret = constr.newInstance().asInstanceOf[LiftCometActor]
ret.callInitCometActor(this, Full(contType), name, defaultXml, attributes)
- ret ! PerformSetupComet
+ ret ! PerformSetupComet2(if (ret.sendInitialReq_?)
+ S.request.map(_.snapshot) else Empty)
ret.asInstanceOf[LiftCometActor]
} or tryo((e: Throwable) => logger.info("Comet find by type Failed to instantiate " + cls.getName, e)) {
val constr = cls.getConstructor(this.getClass, classOf[Box[String]], classOf[NodeSeq], classOf[Map[String, String]])
val ret = constr.newInstance(this, name, defaultXml, attributes).asInstanceOf[LiftCometActor];
- ret ! PerformSetupComet
+ ret ! PerformSetupComet2(if (ret.sendInitialReq_?)
+ S.request.map(_.snapshot) else Empty)
ret.asInstanceOf[LiftCometActor]
}
})

0 comments on commit f26ddf2

Please sign in to comment.