Type of CometActor reply

51 views
Skip to first unread message

bjoern...@gmail.com

unread,
Feb 16, 2012, 3:32:32 PM2/16/12
to Lift
Hi!

How do you determine the type of an answer from a cometactor?
Currently i am doing this:

var weekResults = scala.collection.mutable.Map[Tuple2[String, String],
LAFuture[Any]]()
...
weeks.weeks.map { w =>
weekResults(w) = apiHandler !< PropertyUpdater(id, Full(w._1),
Full(w._2), List("ga:visits", "ga:pageviews"))
}
...check that they are all satisfied ....

weekResults.map { w =>
val updaterResult =
w._2.asInstanceOf[LAFuture[PropertyUpdaterResult]].get
...
}

But i cant guarantee or really check that I got a
LAFuture[PropertyUpdaterResult there, can I?

Thanks in advance
Björn

David Pollak

unread,
Feb 16, 2012, 5:51:18 PM2/16/12
to lif...@googlegroups.com
On Thu, Feb 16, 2012 at 12:32 PM, bjoern...@googlemail.com <bjoern...@gmail.com> wrote:
Hi!

How do you determine the type of an answer from a cometactor?

CometActor is unityped... you get and send Any to and from Actors.  
 
Currently i am doing this:

var weekResults = scala.collection.mutable.Map[Tuple2[String, String],
LAFuture[Any]]()
...
weeks.weeks.map { w =>
 weekResults(w) = apiHandler !< PropertyUpdater(id, Full(w._1),
Full(w._2), List("ga:visits", "ga:pageviews"))
}
...check that they are all satisfied ....

weekResults.map { w =>
 val updaterResult =
w._2.asInstanceOf[LAFuture[PropertyUpdaterResult]].get
...
}


If you do:

val future: LAFuture[Any] = ...

Then:

val result = future.get(2000).asA[PropertyUpdaterResult] // Box[PropertyUpdaterResult]

 
But i cant guarantee or really check that I got a
LAFuture[PropertyUpdaterResult there, can I?

Thanks in advance
Björn

--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code



--
Visi.Pro, Cloud Computing for the Rest of Us http://visi.pro
Lift, the simply functional web framework http://liftweb.net


bjoern...@gmail.com

unread,
Feb 17, 2012, 4:06:01 PM2/17/12
to Lift
Hi,

thanks for your help.
I have a follow-up question which breaks my head, why this is not
working as expected. :/

This is my highPriorioty-Handler:
override def highPriority = { case
AccountDetailGraphTick => {
if (satisfied) {
updateGraph
} else {
partialUpdate(SetHtml(elemId, <p>Updating:s {satisfied}
{UUID.randomUUID.toString}</p>))
ping
}
}
}

This is how my satisfied-function is defined:
private def satisfied:Boolean = {
weekResults.size == satisfaction
}

private def satisfaction:Int = {
weekResults.foldLeft(0)((a, t) => if (t._2.isSatisfied) a+1 else
a)
}

In theory i only want to call updateGraph only when all LAFutures are
satisfied. But in the updateGraph they say that they arent satisfied?
I guess you need more code to know what i am talking about / reproduce
it?

Thanks in advance
Björn

On 16 Feb., 23:51, David Pollak <feeder.of.the.be...@gmail.com> wrote:
> On Thu, Feb 16, 2012 at 12:32 PM, bjoernhaeu...@googlemail.com <
> Visi.Pro, Cloud Computing for the Rest of Ushttp://visi.pro
> Lift, the simply functional web frameworkhttp://liftweb.net

Diego Medina

unread,
Feb 18, 2012, 4:42:59 AM2/18/12
to lif...@googlegroups.com
it would help if you could put together a fully running sample, but If
I'm guessing your app right, you may want to change it a bit.
Instead of pinging your comet and checking if work has been completed
by all the Futures, you may want to do something like what I describe
here:
http://blog.fmpwizard.com/54204619
and to decide when is the right time to send a "task complete "
message to your comet actor, you can use a for comprehension , which
will only reach the end if all Futures return a value.

Hope that helps

Diego

--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://www.fmpwizard.com

bjoern...@gmail.com

unread,
Feb 18, 2012, 8:36:13 AM2/18/12
to Lift
Thanks for your help.

As of now I think I am tolly misunderstanding the concept behing
CometActors. I have put some code together:
https://github.com/bjoernhaeuser/lift-cometactor-satisfied

I though that the "satisfaction"-count should get periodically
updated, but it isnt. Its just is "intialized" and than "gotcha".
Whats wrong with my brain?

Thanks in advance
Björn

On 18 Feb., 10:42, Diego Medina <di...@fmpwizard.com> wrote:
> it would help if you could put together a fully running sample, but If
> I'm guessing your app right, you may want to change it a bit.
> Instead of pinging your comet and checking if work has been completed
> by all the Futures, you may  want to do something like what I describe
> here:http://blog.fmpwizard.com/54204619
> and to decide when is the right time to send a "task complete "
> message to your comet actor, you can use a for comprehension , which
> will only reach the end if all Futures return a value.
>
> Hope that helps
>
>   Diego
>
> On Fri, Feb 17, 2012 at 4:06 PM, bjoernhaeu...@googlemail.com

Diego Medina

unread,
Feb 19, 2012, 12:55:31 AM2/19/12
to lif...@googlegroups.com

On Sat, Feb 18, 2012 at 8:36 AM, bjoern...@googlemail.com <bjoern...@gmail.com> wrote:
> Thanks for your help.


> I though that the "satisfaction"-count should get periodically
> updated, but it isnt. Its just is "intialized" and than "gotcha".

On localSetup, you set the Map weekResults,

then on the first Tick you call
if (satisfied) {

which always returns true because it is defined as

private def satisfied:Boolean = {
weekResults.size == satisfaction
}

and

weekResults.size is always 100 because it is init'ed in localSetup to hold one LAFuture per value of weeks

Unfortunately I can't rework your sample project right now (not enough time, sorry), but I can give you a few pointers of what I would do, and that may help you get going.

1- I wouldn't setup so many thing on localSetup, It is better to tell the CometActor ( and any other actor for that matter), to do things based on messages. In your case, what action is the one that would trigger the work> is it a button click?, a file upload?, if it is a button, have the button send a message to the cometActor to start start the work.

2- I wouldn't use a LAFuture, this is very personal, and others may disagree, but I prefer to send messages to actors, let them do the work and then send me another message once they are done. In your case you have one actor, the CometActor, that can send a message to the LiftActor that does the APIHandler, as both are actors, they can send messages to each other.

3- How would you know when all 100 items have been processed?
I would have a second LiftActor that has a
private var cnt: Int = 0 //or choose something that makes sens for your app

and then, the flow would be:

1- CometActor sends a message to the LiftActor APIHandler to do work (regular message using !
2- APIHandler does its work and once done sends a message to the Counter LiftActor
3- Counter LiftActor knows what the total number should be, so it increases the internal counter and compares it to the final number, once those match, it sends a message to the comet actor with the final result, oh right, when it increases the counter, it can send the comet a message saying it just finished that one item.

I hope I understood what you are trying to do.

Regards

  Diego


David Pollak

unread,
Feb 20, 2012, 10:40:31 AM2/20/12
to lif...@googlegroups.com
Today is my Lift-day.  I'll try to work out some example code for you.
Visi.Pro, Cloud Computing for the Rest of Us http://visi.pro
Lift, the simply functional web framework http://liftweb.net

David Pollak

unread,
Feb 20, 2012, 3:24:17 PM2/20/12
to lif...@googlegroups.com
Okay, I've updated your example.  Please see https://github.com/dpp/lift-cometactor-satisfied/commit/104d3bef127837db3e50042c1e689670cdc1ec85

I've made the following changes:
  • Used S.sendCometActorMessage to send data to the CometActor
  • Updated the futures code so that it uses a for-comprehension (foreach) to run the computation each time the future becomes satisfied
  • Made it clear that there are 2 futures: the one returned by !< and the one returned by the reply... so !< returns LAFuture[LAFuture[...]]
  • Made everything message based rather than if-testing.  Actors are message-based
Hope this helps you better understand how to use LiftActors and LAFutures.

On Sat, Feb 18, 2012 at 5:36 AM, bjoern...@googlemail.com <bjoern...@gmail.com> wrote:



--
Visi.Pro, Cloud Computing for the Rest of Us http://visi.pro
Lift, the simply functional web framework http://liftweb.net

bjoern...@gmail.com

unread,
Feb 21, 2012, 5:31:50 PM2/21/12
to Lift
I dont know how to thank you. Your example code made me understand
much more of the way lift works. Thanks so much.

From your answer and the answers Diego provided a new question
raised.
I should use messages over LAFutures (they are not really a
replacement for another), shouldnt I?

Thanks again, you really helped a lot with your answer.
Björn


On 20 Feb., 21:24, David Pollak <feeder.of.the.be...@gmail.com> wrote:
> Okay, I've updated your example.  Please seehttps://github.com/dpp/lift-cometactor-satisfied/commit/104d3bef12783...
>
> I've made the following changes:
>
>    - Used S.sendCometActorMessage to send data to the CometActor
>    - Updated the futures code so that it uses a for-comprehension (foreach)
>    to run the computation each time the future becomes satisfied
>    - Made it clear that there are 2 futures: the one returned by !< and the
>    one returned by the reply... so !< returns LAFuture[LAFuture[...]]
>    - Made everything message based rather than if-testing.  Actors are
>    message-based
>
> Hope this helps you better understand how to use LiftActors and LAFutures.
>
> On Sat, Feb 18, 2012 at 5:36 AM, bjoernhaeu...@googlemail.com <

David Pollak

unread,
Feb 21, 2012, 5:42:31 PM2/21/12
to lif...@googlegroups.com
On Tue, Feb 21, 2012 at 2:31 PM, bjoern...@googlemail.com <bjoern...@gmail.com> wrote:
I dont know how to thank you. Your example code made me understand
much more of the way lift works. Thanks so much.

Sure thing.  The code is mostly about how Actors work.
 

From your answer and the answers Diego provided a new question
raised.
I should use messages over LAFutures (they are not really a
replacement for another), shouldnt I?

Any time you want an Actor (CometActor or regular Actor) to do something, you should send a message to the Actor.  The time it takes to process the message should be minimal as an Actor can process no other messages while it's processing a given message and blocking on external resources while servicing the message.

For your purposes, I'd use net.liftweb.util.Schedule to schedule lots of threads to go out and do lots of jobs against external resources.  At the end of each thread's job, the thread should send a message to the Actor that spawned it with the information from the job.  I wouldn't use Futures, I'd just spawn a bunch of threads and then send a bunch of messages.



--
Visi.Pro, Cloud Computing for the Rest of Us http://visi.pro
Lift, the simply functional web framework http://liftweb.net

Björn Häuser

unread,
Feb 26, 2012, 10:42:25 AM2/26/12
to lif...@googlegroups.com
Hi David,

as you and Diego suggest I changed the code to use only Messages. Got rid of LAFutures and localSetup also.
I adapted your changes to my code in my "real" code and it works pretty well.

Thanks again
Björn

David Pollak

unread,
Feb 26, 2012, 12:07:04 PM2/26/12
to lif...@googlegroups.com
Glad to hear it.

2012/2/26 Björn Häuser <bjoern...@gmail.com>

Björn

--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code
Reply all
Reply to author
Forward
0 new messages