On Mon, Sep 28, 2009 at 7:29 PM, Jack Widman <jack.wid...@gmail.com> wrote:
> 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. > Without a complete running (or failing) example, I can't really help out a lot... but I have put a few comments inline. > 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 > state should be private to the Actor, not public. > > 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>") > } > Why String + XML -> XML? Why intermediate mutable state? How about <span id="score"><table> { for {page <- pages} yield <tr><td><a href={page.url}>{page.render></a></td></tr> } </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))) > Why partialUpdate rather than just doing a reRender? You're only saving a <span></span> which is not much of a savings. > ActorPing.schedule(this,Tick, 1000L) > Why do this once a second? Why not send a message from PageQueue when things change? > } > } > } > > 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 >> >> >> > > > > -- 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 -~----------~----~----~----~------~----~------~--~---