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