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.

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
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
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