CometActor and render

35 views
Skip to first unread message

jack

unread,
Nov 8, 2009, 3:12:04 AM11/8/09
to Lift
I have a CometActor. render is called when it is supposed to be but I
don't see the changes. If I refresh the page at anytime, I do see the
changes. Any idea what might cause this?

jack

unread,
Nov 8, 2009, 3:14:06 AM11/8/09
to Lift
By the way, I know that when render is called, all the variables have
the right values. I just don't see it on the screen unless I refresh
it.

Timothy Perrett

unread,
Nov 8, 2009, 5:31:29 AM11/8/09
to lif...@googlegroups.com
Without posting your code it's going to be tough to help you.

Cheers, Tim

Sent from my iPhone

Jack Widman

unread,
Nov 8, 2009, 6:47:29 PM11/8/09
to lif...@googlegroups.com
Sorry. Here it is:   As I said, I know that when render is called, foo.getValue has the right value. But it does not show on the screen, unless I refresh the browser.

package com.foo.comet

import net.liftweb._
import http._
import js._
import JsCmds._
import net.liftweb.util._
import net.liftweb.http._
import _root_.scala.xml._
import scala.actors._
import com.authoritude.snippet._
import scala.collection.mutable.Queue
import net.liftweb.http.SessionVar


class MyComet extends CometActor {
 
  override def defaultPrefix = Full("auth")
 
  private var foos = FooManager.getFoos

  def createDisplay(foos:List[Foo]):NodeSeq = {
    <span id="go"><table>
    {
      for {foo <- foos} yield <tr><td>{foo.getValue}</td></tr>
    }
  
    </table></span>
  }
 
  def render = { bind("foo" -> createDisplay(foos)) }
 
  override def localSetup = {
    super.localSetup
    this ! Tick
  }
 
  var foo:Foo = null 
  override def lowPriority = {
    case Tick => {
      foo=FooQueue.getLatest
      if (foo!=null && foo.getValue > -1) {
    blogs = FooManager.process(foo, foos)
      } else if (foo!=null){
    foos = foos.remove((f:Foo)=>(f.id==foo.id))
      }
      reRender(false)
      this ! Tick
    }
  }
}

case class Tick
--
Jack Widman

co-founder / cto,  Authoritude, Inc.

203-641-9355

jack

unread,
Nov 8, 2009, 7:03:20 PM11/8/09
to Lift
One more thing. 'foo's get added to the FooQueue periodically.
> On Sun, Nov 8, 2009 at 5:31 AM, Timothy Perrett <timo...@getintheloop.eu>wrote:
>
>
>
>
>
> > Without posting your code it's going to be tough to help you.
>
> > Cheers, Tim
>
> > Sent from my iPhone
>

David Pollak

unread,
Nov 8, 2009, 11:35:19 PM11/8/09
to lif...@googlegroups.com
Jack,

I reproduced your code and it seems to work fine.  I've enclosed a working copy.

Some comments about your code:
  • The foos variable and the foo variable may be getting confused in the code... the render method may be rendering the same thing based on the unchanging foos variable.
  • Doing null testing is a sign that you have logic errors in your code.  I strongly recommend using either Box or Option for everything that can logically not contain a value/reference.  If you're bridging out to Java code and are expecting null from the Java code, write a small bridge that will wrapper the Java return values in Box/Option.
  • You have a case class (Tick) that contains no parameters.  Please use a case object instead.
  • Your Tick look is a spin loop.  You fire a Tick message as part of processing the Tick message.  I would suggest that if you're polling, that you have a reasonable poll interval, otherwise you'll starve your CPU.  Further, having reRender on each loop through means that you're forcing a lot of bytes over the wire rather than only doing a reRender on changed values.
Thanks,

David
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics
yaker.tgz

Jack Widman

unread,
Nov 9, 2009, 2:28:31 AM11/9/09
to lif...@googlegroups.com
Thanks David. This is a big help. Can you tell me exactly how lowPriority, mediumPriorty and highPriority work? When are they called?

David Pollak

unread,
Nov 9, 2009, 9:19:07 AM11/9/09
to lif...@googlegroups.com
On Sun, Nov 8, 2009 at 11:28 PM, Jack Widman <jack....@gmail.com> wrote:
Thanks David. This is a big help. Can you tell me exactly how lowPriority, mediumPriorty and highPriority work? When are they called?

When a message comes into the Actor's mailbox, the Actor determines if it can handle the message.  CometActors have a set of messages they can (must) handle related to being a CometActor, but each CometActor is going to be customized, so it must be able to handle extra messages.  The CometActor builds a PartialFunction to determine if it can handle messages by:

val handler = highPriority orElse builtIn orElse mediumPriority orElse lowPriority

The handler (built each time a message is tested or dispatched, so you can dynamically change the message handling) is tested against the message (isDefinedAt) and if it can handle the message, the message is removed from the mailbox and dispatched (apply).  If the message cannot be dispatched, the next message in the mailbox is tested and so on until there are no more messages that can be dispatched.
 

Jack Widman

unread,
Nov 10, 2009, 1:10:30 AM11/10/09
to lif...@googlegroups.com
The only difference between your working code and mine is that mine has a process in the background that is always running and puts Foo objects on a queue whenever they are ready. Where can I start this long running process so that it doesn't interfere with the lowPriority method that takes things off the queue and rerenders the page. I tried starting the process in its own Actor that I start in localSetup but it seems somehow to be blocking the lowPriority method from doing its thing.

On Sun, Nov 8, 2009 at 11:35 PM, David Pollak <feeder.of...@gmail.com> wrote:

David Pollak

unread,
Nov 10, 2009, 1:27:03 AM11/10/09
to lif...@googlegroups.com
On Mon, Nov 9, 2009 at 10:10 PM, Jack Widman <jack....@gmail.com> wrote:
The only difference between your working code and mine is that mine has a process in the background that is always running and puts Foo objects on a queue whenever they are ready. Where can I start this long running process so that it doesn't interfere with the lowPriority method that takes things off the queue and rerenders the page. I tried starting the process in its own Actor that I start in localSetup but it seems somehow to be blocking the lowPriority method from doing its thing.

I have no idea what this means... sorry.

Please post actual runnable code and we can help you debug.

Jack Widman

unread,
Nov 10, 2009, 9:45:11 AM11/10/09
to lif...@googlegroups.com
Sorry. Just reread my past post and it is indeed unclear. I will post running code tonight. I very much appreciate your help.

Jack Widman

unread,
Nov 11, 2009, 11:26:16 PM11/11/09
to lif...@googlegroups.com
David,

I have attached my code. It runs but does not behave as I intended it to. The code does a web search on the term "scala" and displays a list of URLs of the results. Next to each URL it says "Page Length : -1". A process is running in the background which takes each URL, goes out and gets the page and takes the length of the page. The length of that page is then supposed to immediately appear on the page next to that URL. I put the lengths on a queue, as they come in, and I have the Comet page poll the queue and display the results. It would probably be better to have the results send a message to the Comet class so the page is only re-rendered when there is a change but for now I am polling.

I can see the lengths coming in and being put on the queue, but the Comet page is not getting them till they are all retrieved. (This takes way too long and nothing changes on the screen till its too late). I need them to appear as they come in. Occasionally I can see a length being retrieved and the Comet page finds it but even then it is not displayed until all the lengths are in.   I know this is not very clear but I think it will be clear from the code.

I also know there are a lot of places in the code which can be improved and I welcome all of your input but what I would love is to have these numbers appear on the page as they they are retrieved. I have been stumped by this for a while and I suspect that somebody who knows Lift well might see the problem right away.

The class that retrieves the page lengths is called Calculator and the queue is called SourceQueue. The classes are pretty small so hopefully it will be clear what is going on. I want you to know I think it is incredible how responsive you and the group are and I look forward to using Lift in the future.

Thanks so much.

Jack


On Tue, Nov 10, 2009 at 1:27 AM, David Pollak <feeder.of...@gmail.com> wrote:
widman.tgz

jack

unread,
Nov 11, 2009, 11:29:58 PM11/11/09
to Lift
one more thing: I also ran the code without the piece that retrieves
web pages and gets their length. Instead I just had the Calculator
class sleep for 10 seconds (which is longer than the http request
takes) and then return a random number. This worked fine. I can't see
what the difference is.
> On Tue, Nov 10, 2009 at 1:27 AM, David Pollak <feeder.of.the.be...@gmail.com
>
> > wrote:
>
> > On Mon, Nov 9, 2009 at 10:10 PM, Jack Widman <jack.wid...@gmail.com>wrote:
>
> >> The only difference between your working code and mine is that mine has a
> >> process in the background that is always running and puts Foo objects on a
> >> queue whenever they are ready. Where can I start this long running process
> >> so that it doesn't interfere with the lowPriority method that takes things
> >> off the queue and rerenders the page. I tried starting the process in its
> >> own Actor that I start in localSetup but it seems somehow to be blocking the
> >> lowPriority method from doing its thing.
>
> > I have no idea what this means... sorry.
>
> > Please post actual runnable code and we can help you debug.
>
> >> On Sun, Nov 8, 2009 at 11:35 PM, David Pollak <
> >> feeder.of.the.be...@gmail.com> wrote:
>
> >>> Jack,
>
> >>> I reproduced your code and it seems to work fine.  I've enclosed a
> >>> working copy.
>
> >>> Some comments about your code:
>
> >>>    - The foos variable and the foo variable may be getting confused in
> >>>    the code... the render method may be rendering the same thing based on the
> >>>    unchanging foos variable.
> >>>    - Doing null testing is a sign that you have logic errors in your
> >>>    code.  I strongly recommend using either Box or Option for everything that
> >>>    can logically not contain a value/reference.  If you're bridging out to Java
> >>>    code and are expecting null from the Java code, write a small bridge that
> >>>    will wrapper the Java return values in Box/Option.
> >>>    - You have a case class (Tick) that contains no parameters.  Please
> >>>    use a case object instead.
> >>>    - Your Tick look is a spin loop.  You fire a Tick message as part of
> >>>    processing the Tick message.  I would suggest that if you're polling, that
> >>>    you have a reasonable poll interval, otherwise you'll starve your CPU.
> >>>    Further, having reRender on each loop through means that you're forcing a
> >>>    lot of bytes over the wire rather than only doing a reRender on changed
> >>>    values.
>
> >>> Thanks,
>
> >>> David
>
> >>>>> On 8 Nov 2009, at 08:14, jack <jack.wid...@gmail.com> wrote:
>
> >>>>> > By the way, I know that when render is called, all the variables have
> >>>>> > the right values. I just don't see it on the screen unless I refresh
> >>>>> > it.
>
> >>>>> > On Nov 8, 3:12 am, jack <jack.wid...@gmail.com> wrote:
> >>>>> >> I have a CometActor. render is called when it is supposed to be but
> >>>>> I
> >>>>> >> don't see the changes. If I refresh the page at anytime, I do see
> >>>>> the
> >>>>> >> changes. Any idea what might cause this?
>
> >>>> --
> >>>> Jack Widman
>
> >>>> co-founder / cto,  Authoritude, Inc.
>
> >>>> 203-641-9355
>
> >>> --
> >>> Lift, the simply functional web frameworkhttp://liftweb.net
> >>> Beginning Scalahttp://www.apress.com/book/view/1430219890
> >>> Follow me:http://twitter.com/dpp
> >>> Surf the harmonics
>
> >> --
> >> Jack Widman
>
> >> co-founder / cto,  Authoritude, Inc.
>
> >> 203-641-9355
>
> > --
> > Lift, the simply functional web frameworkhttp://liftweb.net
> > Beginning Scalahttp://www.apress.com/book/view/1430219890
> > Follow me:http://twitter.com/dpp
> > Surf the harmonics
>
>
>
>  widman.tgz
> 187KViewDownload

Randinn

unread,
Nov 12, 2009, 4:05:20 PM11/12/09
to Lift
I'm not trying to change the subject but I was wondering if you looked
at Databinder Dispatch http://databinder.net/dispatch/About for your
url calls?
> On Tue, Nov 10, 2009 at 1:27 AM, David Pollak <feeder.of.the.be...@gmail.com
>
> > wrote:
>
> > On Mon, Nov 9, 2009 at 10:10 PM, Jack Widman <jack.wid...@gmail.com>wrote:
>
> >> The only difference between your working code and mine is that mine has a
> >> process in the background that is always running and puts Foo objects on a
> >> queue whenever they are ready. Where can I start this long running process
> >> so that it doesn't interfere with the lowPriority method that takes things
> >> off the queue and rerenders the page. I tried starting the process in its
> >> own Actor that I start in localSetup but it seems somehow to be blocking the
> >> lowPriority method from doing its thing.
>
> > I have no idea what this means... sorry.
>
> > Please post actual runnable code and we can help you debug.
>
> >> On Sun, Nov 8, 2009 at 11:35 PM, David Pollak <
> >> feeder.of.the.be...@gmail.com> wrote:
>
> >>> Jack,
>
> >>> I reproduced your code and it seems to work fine.  I've enclosed a
> >>> working copy.
>
> >>> Some comments about your code:
>
> >>>    - The foos variable and the foo variable may be getting confused in
> >>>    the code... the render method may be rendering the same thing based on the
> >>>    unchanging foos variable.
> >>>    - Doing null testing is a sign that you have logic errors in your
> >>>    code.  I strongly recommend using either Box or Option for everything that
> >>>    can logically not contain a value/reference.  If you're bridging out to Java
> >>>    code and are expecting null from the Java code, write a small bridge that
> >>>    will wrapper the Java return values in Box/Option.
> >>>    - You have a case class (Tick) that contains no parameters.  Please
> >>>    use a case object instead.
> >>>    - Your Tick look is a spin loop.  You fire a Tick message as part of
> >>>    processing the Tick message.  I would suggest that if you're polling, that
> >>>    you have a reasonable poll interval, otherwise you'll starve your CPU.
> >>>    Further, having reRender on each loop through means that you're forcing a
> >>>    lot of bytes over the wire rather than only doing a reRender on changed
> >>>    values.
>
> >>> Thanks,
>
> >>> David
>
> >>>>> On 8 Nov 2009, at 08:14, jack <jack.wid...@gmail.com> wrote:
>
> >>>>> > By the way, I know that when render is called, all the variables have
> >>>>> > the right values. I just don't see it on the screen unless I refresh
> >>>>> > it.
>
> >>>>> > On Nov 8, 3:12 am, jack <jack.wid...@gmail.com> wrote:
> >>>>> >> I have a CometActor. render is called when it is supposed to be but
> >>>>> I
> >>>>> >> don't see the changes. If I refresh the page at anytime, I do see
> >>>>> the
> >>>>> >> changes. Any idea what might cause this?
>
> >>>> --
> >>>> Jack Widman
>
> >>>> co-founder / cto,  Authoritude, Inc.
>
> >>>> 203-641-9355
>
> >>> --
> >>> Lift, the simply functional web frameworkhttp://liftweb.net
> >>> Beginning Scalahttp://www.apress.com/book/view/1430219890
> >>> Follow me:http://twitter.com/dpp
> >>> Surf the harmonics
>
> >> --
> >> Jack Widman
>
> >> co-founder / cto,  Authoritude, Inc.
>
> >> 203-641-9355
>
> > --
> > Lift, the simply functional web frameworkhttp://liftweb.net
> > Beginning Scalahttp://www.apress.com/book/view/1430219890
> > Follow me:http://twitter.com/dpp
> > Surf the harmonics
>
>
>
>  widman.tgz
> 187KViewDownload

Jack Widman

unread,
Nov 12, 2009, 4:08:03 PM11/12/09
to lif...@googlegroups.com
I did and its actually in the code I attached. In one place I use Dispatch and in another place I use httpclient directly. I intend to use Dispatch for everything.

jack

unread,
Nov 12, 2009, 4:40:33 PM11/12/09
to Lift
David,

I hope its clear from the code what the problem is. If you want me to,
I will give a more detailed description of how the code is supposed to
work.

Jack
> On Tue, Nov 10, 2009 at 1:27 AM, David Pollak <feeder.of.the.be...@gmail.com
>
> > wrote:
>
> > On Mon, Nov 9, 2009 at 10:10 PM, Jack Widman <jack.wid...@gmail.com>wrote:
>
> >> The only difference between your working code and mine is that mine has a
> >> process in the background that is always running and puts Foo objects on a
> >> queue whenever they are ready. Where can I start this long running process
> >> so that it doesn't interfere with the lowPriority method that takes things
> >> off the queue and rerenders the page. I tried starting the process in its
> >> own Actor that I start in localSetup but it seems somehow to be blocking the
> >> lowPriority method from doing its thing.
>
> > I have no idea what this means... sorry.
>
> > Please post actual runnable code and we can help you debug.
>
> >> On Sun, Nov 8, 2009 at 11:35 PM, David Pollak <
> >> feeder.of.the.be...@gmail.com> wrote:
>
> >>> Jack,
>
> >>> I reproduced your code and it seems to work fine.  I've enclosed a
> >>> working copy.
>
> >>> Some comments about your code:
>
> >>>    - The foos variable and the foo variable may be getting confused in
> >>>    the code... the render method may be rendering the same thing based on the
> >>>    unchanging foos variable.
> >>>    - Doing null testing is a sign that you have logic errors in your
> >>>    code.  I strongly recommend using either Box or Option for everything that
> >>>    can logically not contain a value/reference.  If you're bridging out to Java
> >>>    code and are expecting null from the Java code, write a small bridge that
> >>>    will wrapper the Java return values in Box/Option.
> >>>    - You have a case class (Tick) that contains no parameters.  Please
> >>>    use a case object instead.
> >>>    - Your Tick look is a spin loop.  You fire a Tick message as part of
> >>>    processing the Tick message.  I would suggest that if you're polling, that
> >>>    you have a reasonable poll interval, otherwise you'll starve your CPU.
> >>>    Further, having reRender on each loop through means that you're forcing a
> >>>    lot of bytes over the wire rather than only doing a reRender on changed
> >>>    values.
>
> >>> Thanks,
>
> >>> David
>
> >>>>> On 8 Nov 2009, at 08:14, jack <jack.wid...@gmail.com> wrote:
>
> >>>>> > By the way, I know that when render is called, all the variables have
> >>>>> > the right values. I just don't see it on the screen unless I refresh
> >>>>> > it.
>
> >>>>> > On Nov 8, 3:12 am, jack <jack.wid...@gmail.com> wrote:
> >>>>> >> I have a CometActor. render is called when it is supposed to be but
> >>>>> I
> >>>>> >> don't see the changes. If I refresh the page at anytime, I do see
> >>>>> the
> >>>>> >> changes. Any idea what might cause this?
>
> >>>> --
> >>>> Jack Widman
>
> >>>> co-founder / cto,  Authoritude, Inc.
>
> >>>> 203-641-9355
>
> >>> --
> >>> Lift, the simply functional web frameworkhttp://liftweb.net
> >>> Beginning Scalahttp://www.apress.com/book/view/1430219890
> >>> Follow me:http://twitter.com/dpp
> >>> Surf the harmonics
>
> >> --
> >> Jack Widman
>
> >> co-founder / cto,  Authoritude, Inc.
>
> >> 203-641-9355
>
> > --
> > Lift, the simply functional web frameworkhttp://liftweb.net
> > Beginning Scalahttp://www.apress.com/book/view/1430219890
> > Follow me:http://twitter.com/dpp
> > Surf the harmonics
>
>
>
>  widman.tgz
> 187KViewDownload

David Pollak

unread,
Nov 12, 2009, 5:03:25 PM11/12/09
to lif...@googlegroups.com
Jack,

Your pom.xml file mixes Scala 2.7.3, Lift 1.0 and Lift 1.1-M6... this doesn't work.

You have to be running with the same version of Lift.

I'll look at the actual code and report more in a little while.

Thanks,

David

Jack Widman

unread,
Nov 12, 2009, 5:10:06 PM11/12/09
to lif...@googlegroups.com
Ok. I actually had this problem before I upgraded to M6.

David Pollak

unread,
Nov 12, 2009, 5:12:19 PM11/12/09
to lif...@googlegroups.com
Jack,

The issues you're seeing are not Lift related.  You are not using Actors correctly.  Please see Philipp Haller's preso on Actors: http://lamp.epfl.ch/~phaller/doc/ScalaActors.pdf

Please also look at the Actor chapters in Beginning Scala or Programming in Scala.

Thanks,

David

Jack Widman

unread,
Nov 12, 2009, 5:16:54 PM11/12/09
to lif...@googlegroups.com
Will do. One more small question How do I send a message to the Comet Actor from another class? Can the CometActor be an object instead of a class? In the code

X ! messageToCometActor,   what is X? I don't have a variable that holds the instance of the CometActor.

Jack Widman

unread,
Nov 12, 2009, 5:25:52 PM11/12/09
to lif...@googlegroups.com
Is it that I am putting things on a Queue from within an the Calculator Actor and having the CometActor retrieve them from the Queue? Is that the problem?  I will read up on actors but it would help if you could tell me (if only briefly) what you saw about my actor code that is wrong.
 Thanks.

David Pollak

unread,
Nov 12, 2009, 5:32:44 PM11/12/09
to lif...@googlegroups.com
On Thu, Nov 12, 2009 at 2:16 PM, Jack Widman <jack....@gmail.com> wrote:
Will do. One more small question How do I send a message to the Comet Actor from another class? Can the CometActor be an object instead of a class? In the code

Lift instantiates a new CometActor each time it needs one.  If you have a singleton CometActor, you'd be sharing state across all sessions and that would be impossible to manage.
 

X ! messageToCometActor,   what is X? I don't have a variable that holds the instance of the CometActor.

If the CometActor is a listener to another service, you can register the instance of the CometActor as a listener during localSetup and unregister during localShutdown.

See that Chat example in lift-examples/example

Jack Widman

unread,
Nov 12, 2009, 5:35:20 PM11/12/09
to lif...@googlegroups.com
Thanks.

David Pollak

unread,
Nov 12, 2009, 5:41:15 PM11/12/09
to lif...@googlegroups.com
On Thu, Nov 12, 2009 at 2:25 PM, Jack Widman <jack....@gmail.com> wrote:
Is it that I am putting things on a Queue from within an the Calculator Actor and having the CometActor retrieve them from the Queue? Is that the problem?  I will read up on actors but it would help if you could tell me (if only briefly) what you saw about my actor code that is wrong.

The act method in an actor sets up the receive/react loop.  It is not a "background thread" in and of itself.  Actors are not "background threads" they are things that process messages sent to them with the ! method.  You set up the message handling in the receive/react loop.

Further, mixing method calls and Actor message handling is wicked dangerous (especially without synchronized blocks).  Choose either a traditional threading model or an Actor-based model, but not both.

Jack Widman

unread,
Nov 12, 2009, 5:44:17 PM11/12/09
to lif...@googlegroups.com
got it. I was mixing metaphors.

Randinn

unread,
Nov 13, 2009, 6:53:32 PM11/13/09
to Lift
Ah, nice, just checking if you knew about it as an option.

On Nov 13, 8:08 am, Jack Widman <jack.wid...@gmail.com> wrote:
> I did and its actually in the code I attached. In one place I use Dispatch
> and in another place I use httpclient directly. I intend to use Dispatch for
> everything.
>
>
>
> On Thu, Nov 12, 2009 at 4:05 PM, Randinn <rand...@gmail.com> wrote:
>
> > I'm not trying to change the subject but I was wondering if you looked
> > at Databinder Dispatchhttp://databinder.net/dispatch/Aboutfor your
Reply all
Reply to author
Forward
0 new messages