On Tue, Sep 29, 2009 at 8:00 AM, Jack Widman <jack.wid...@gmail.com> wrote:
> Thanks. I will adapt these changes and if its still not working I will post > the code so you can run it. Also, I admit, I have a ways to go in the art of > functional programming. Rule #1 - don't use anything mutable unless you have a good reason. Document your reason in your code. That'll make you think Rule #2 - take advantage of the type system. having built-in XML means not devolving into Strings which are pretty much untyped > > > On Tue, Sep 29, 2009 at 12:50 AM, David Pollak < > feeder.of.the.be...@gmail.com> wrote: > >> >> >> 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 >> >> >> > > > > -- 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 -~----------~----~----~----~------~----~------~--~---