Thanks David so much for this example. It is very cool to accomplish this in
such a small amount of code! I am trying to adapt my code to work like this
and it would help me if you could look at this (short) piece of code and
tell me whats wrong with it. This code is supposed to display a list of
pages and then actors in the background process each page. As each page is
processed, the processed page is put into a Queue called PageQueue, and as
each new page occurs in the Queue, the main page is rerendered. When I run
it, the following happens:

   1. The initial list of pages is successfully displayed
   2. The actors in the background do their thing but the main page never
   shows the modified pages
   3. If I wait awhile and then refresh the main page, the modified pages do
   appear.
   4. Then I see the following exception:

This page contains the following errors: error on line 14 at column 16:
Namespace prefix auth on score is not defined
Below is a rendering of the page up to the first error.
Here is the code:

package com.authoritude.comet

import net.liftweb.http.SHtml
import net.liftweb.http.S
import _root_.net.liftweb.http.js.JE._
import _root_.net.liftweb.http.js.JsCmds._
import scala.xml._
import net.liftweb.http.S
import net.liftweb.http.CometActor
import net.liftweb.http.SessionVar
import net.liftweb.util._
import _root_.scala.xml._
import _root_.net.liftweb.util.Helpers._
import scala.actors._
import scala.collection.mutable.Queue


class BlogComet extends CometActor {

  override def defaultPrefix = Full("auth")

  var pages:List[Page] = PageManager.getPages

  def createDisplay(pages:List[Page]):NodeSeq = {

    var output:String="<span id=\"score\"><table>"
    for (page<-pages) {
      output += <tr><td><a href={page.url}>{page.render}</a></td></tr>
    }
    XML.loadString(output+"</table></span>")
  }

  def render = bind("score" -> listOfPages)

  //new Page objects are arriving in the PageQueue from other threads
  def listOfPages = {
    var page = PageQueue.getLatest
    //modifyPage takes page.getID, finds this page in
    // pages, and modifies it.
    pages = PageManager.modifyPage(page,pages)
    createDisplay(pages)
  }

  ActorPing.schedule(this, Tick, 1000L)

  override def lowPriority : PartialFunction[Any, Unit] = {

    case Tick => {
      partialUpdate(SetHtml("score", createDisplay(pages)))
      ActorPing.schedule(this,Tick, 1000L)
    }
  }
}

case object Tick


I hope this is not to much to ask...



On Mon, Sep 28, 2009 at 12:36 PM, David Pollak <
feeder.of.the.be...@gmail.com> wrote:

> Jack,
> Here's a working example.
>
> Here's the source for the CometActor:
>
>
> package com.liftcode.comet
> import net.liftweb._
> import http._
> import util._
>
> class Background extends CometActor {
>   private val values = new Array[Box[Int]](100)
>
>   // render the information
>   def render =
>   <div>
>     <ul>
>       {
>         values.zipWithIndex.map{
>           case (Full(v), idx) => <li>Item: {idx} is {v}</li>
>           case (_, idx) => <li>Item: {idx} <i>Calculating</i></li>
>         }
>       }
>     </ul>
>   </div>
>
>   // receive the update and re-render
>   override def lowPriority = {
>     case (idx: Int, value: Int) =>
>       values(idx) = Full(value)
>       reRender(false)
>   }
>
>   // fork 100 thread
>   override def localSetup() {
>     super.localSetup()
>     values.zipWithIndex.foreach {
>       case (_, idx) =>
>         (new Thread(
>             new Runnable {
>               def run() {
>                 Thread.sleep(10000 + Helpers.randomLong(10000))
>                 Background.this ! (idx, Helpers.randomInt(1000))
>               }
>             }
>         )).start()
>     }
>   }
> }
>
>
> Note that the render method cannot block.  You must always render the page
> and put placeholders where you will be updating values.
>
> Note also that this code re-renders the entire comet component on each
> update.  This is network inefficient.  Please take a look a the Comet Chat
> example for how to user partial update which is much more network efficient.
>
> Thanks,
>
> David
>
>
> On Sun, Sep 27, 2009 at 8:09 PM, jack <jack.wid...@gmail.com> wrote:
>
>>
>> I am still having this problem so I will post a simple example. Say I
>> want to display a list of the numbers 1 to 100. And suppose I have an
>> object Foo and a method bar, which takes an integer and returns an
>> integer. And bar takes about 10 seconds to return. So I want to
>> display the numbers, run Foo.bar on each of them in the background,
>> and then update the display via comet to replace each integer with bar
>> of it. I got the Clock example to work and I think I understand what
>> is going on there. Could somebody show me how to do this example in
>> terms of the Clock example? Or just a few lines of code to suggest how
>> to do it?
>>
>>
>>
>>
>>
>>
>>
>>
>> On Sep 18, 12:09 pm, "marius d." <marius.dan...@gmail.com> wrote:
>> > On Sep 17, 11:09 pm,jack<jack.wid...@gmail.com> wrote:
>> >
>> > > I have a CometActor which displays a list of urls and at the same time
>> > > launches a bunch of threads each of which gets information about the
>> > > urls and then puts messages about that information in a Queue. On each
>> > > new tick, the CometActor checks the queue and updates its urls.
>> >
>> > > The problem is that I am launching the threads from the CometActor and
>> > > the page is never coming back. It times out.
>> >
>> > So the page never gets rendered? I would recommend using actors and
>> > not really threads but even with threads it shouldn't impact you. But
>> > it also depends on what your code does. Can you post a minimalistic
>> > example?
>> >
>> >
>> >
>> >
>> >
>> > > Is there some general principle about launching threads from a
>> > > CometActor that might explain this behavior?
>>
>>
>
>
> --
> 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
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to