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

Reply via email to