Short version:
Would you find it useful if I added my named comet actor per browser
tab[1] to Lift 2.5?
[1] http://blog.fmpwizard.com/lift-comet-actor-per-tab-library
Long version:
Many times when I work with comet, I find myself needing the same
comet class, but different instances of it, on different browser tabs.
Let's say you have an online store, you visit
http://host.com/item/123 you get one cometactor that knows how to
render an item, but will only update the UI if the item 123 changes.
if you then visit
http://host.com/item/222 on another tab, you also need the same
cometactor that knows how to render an item, but this comet should
only update the UI if the item 222 was modified.
Not only that, but I wanted a way to only send a message to the comets
that were showing the item(s) that were updated, so if item 123 was
updated, I did not want to send a message to the comet 222 and have it
ignore it.
I was able to achieve that by having a dispatcher and an object that
keeps track of who is showing what, etc. I have an even longer
explanation of how it all works at [1]
=====================================
Up until now I had this library only available through github as
source, so people had to clone the repo and build it themselves (I
know there are at least three different people who us it :) ), but now
I can either start publishing it to sonatype, or if enough people
agree and all goes well, it could be integrated into Lift itself (or
maybe there is even a third option).
So, anyone in favor or against it?
[1] http://blog.fmpwizard.com/lift-comet-actor-per-tab-library
Thanks
Diego
--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://www.fmpwizard.com
--
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
Hi Antonio,
SendCometActorMessage can only send messages in the same session, and when I wrote this library I needed to send messages from other places, like a rest api. So I needed some kind of singleton that could be accessed from anywhere.
Thanks for the question
Diego
Sent from my android cell
--
Thanks Torsten.
Diego
Sent from my android cell
On Sat, Mar 24, 2012 at 11:00 AM, Antonio Salazar Cardozo <savedf...@gmail.com> wrote:
> Aha, gotcha! That is indeed a big difference :) Sounds like it could
> definitely be nice to have, though I wonder if before including it in Lift
> it shouldn't be somewhat more generalized… I suppose the listener pattern
> itself is already somewhat generalized in the form of the
> CometListener/ListenerManager pair of traits. Maybe extending those two with
> name support? What I'm thinking is that the functionality itself is useful,
> but perhaps tying it to a singleton isn't ideal. In particular, we use
> similar patterns for our stuff, but we have several different types of
> actors that can take subscriptions.
>
> Though now that I think about it, we do still have a single central actor
> registry… So that point may be entirely moot.
I think so, for example, I have one singleton for the registry (which I'm thinking could be converted into an actor), and then we have several dispatchers that can keep track of different kinds of comet actors.
>
> The other thing that makes me a little nervous is relying on
> localSetup/localShutdown, mostly because I usually find it unfortunate to
> have to remember to call super within a framework, and that's what would
> have to happen if you wanted to use NamedCometActor *and* provide your own
> local setup/shutdown.
It would be great if we could come up with something better.
Thanks
Diego
On Sat, Mar 24, 2012 at 11:00 AM, Antonio Salazar Cardozo <savedf...@gmail.com> wrote:
> Though now that I think about it, we do still have a single central actor
> registry… So that point may be entirely moot.I think so, for example, I have one singleton for the registry (which I'm thinking could be converted into an actor), and then we have several dispatchers that can keep track of different kinds of comet actors.
> The other thing that makes me a little nervous is relying on
> localSetup/localShutdown, mostly because I usually find it unfortunate to
> have to remember to call super within a framework, and that's what would
> have to happen if you wanted to use NamedCometActor *and* provide your own
> local setup/shutdown.It would be great if we could come up with something better.
Thanks
Diego
On Mar 24, 2012 3:20 PM, "Antonio Salazar Cardozo" <savedf...@gmail.com> wrote:
>
>
> On Saturday, March 24, 2012 1:15:16 PM UTC-4, fmpwizard wrote:
>>
>> On Sat, Mar 24, 2012 at 11:00 AM, Antonio Salazar Cardozo <savedf...@gmail.com> wrote:
>> > Though now that I think about it, we do still have a single central actor
>> > registry… So that point may be entirely moot.
>>
>> I think so, for example, I have one singleton for the registry (which I'm thinking could be converted into an actor), and then we have several dispatchers that can keep track of different kinds of comet actors.
>
> Sounds cool!
>
>>
>> > The other thing that makes me a little nervous is relying on
>> > localSetup/localShutdown, mostly because I usually find it unfortunate to
>> > have to remember to call super within a framework, and that's what would
>> > have to happen if you wanted to use NamedCometActor *and* provide your own
>> > local setup/shutdown.
>>
>> It would be great if we could come up with something better.
>
> Actually, I take that back. It looks like the listener stuff is already hooked into the base CometActor's localSetup, so if you want that to run you have to do a super call anyway. Given the fact that that's already there, it seems reasonable to put this stuff in localSetup as well.
Cool
Diego
>
> Otherwise I might have suggested possibly overriding _mediumPriority with a second PF that does what's needed in PerformSetupComet2. The fact that localSetup contains the listener stuff makes me think that's considered a bad idea to begin with though.
>
>>
>> Thanks
>>
>> Diego
>
> Antonio
>
I don't see why we need a library for implementing this. I've done
something similar here: https://github.com/andreak/on-example-rpm
The example-program contains (among other things) a blog and viewing a
blog-entry (post) with comments is done by a comet-actor. This actor has
different instance of it depending of the blog-entry-id, and locale.
This is implemented as having a singleton (object) holding a registry of
"blog-actor servers", one for each combination of blogEntryId-locale.
This registry is also an actor so you send it a message that you want to
lookup a server for a given combination id-locale and it responds. It
also de-registers servers from the registry after a server has no more
listeners (comet-actors). The blog is reachable from the
"blog"-menu-item once you've logged.
Please have a look at the example program and comment if you like.
--
Andreas Joseph Krogh<and...@officenet.no> - mob: +47 909 56 963
Senior Software Developer / CEO - OfficeNet AS - http://www.officenet.no
Public key: http://home.officenet.no/~andreak/public_key.asc
I didn;t mean to say that this library was some kind of revolutionary
code that Lift should have. I found myself copying and pasting this
code into several projects I was working on, so I decided to make it
into a library. Then I thought that people may find it useful, and
some did and are using it.
And then I thought that people may find is useful enough to have it as
part of Lift, which is why I sent this email.
I think that the fact that you and Antonio have done this pattern
before (and I'm sure others have done it too), proves that we may all
benefit from a central implementation, so that we can all make it the
best possible, instead of going on our own and work on it separately.
I think it would also help new users, saving them the time to think
about how to achieve this pattern, and also saving them from running
into bugs that a central implementation already takes care of. For
example, the first implementation I wrote did not have a way to
un-register dead comet actors, then I realized this was a bug so I
added it.
So, do you think it is not worth having it as part of Lift because you
already wrote it, or do you see it as something that is just too
simple to write on your own?
Thanks for your thoughts.
Diego
> --
> 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
--
Hi Andreas, I didn;t mean to say that this library was some kind of revolutionary code that Lift should have. I found myself copying and pasting this code into several projects I was working on, so I decided to make it into a library. Then I thought that people may find it useful, and some did and are using it. And then I thought that people may find is useful enough to have it as part of Lift, which is why I sent this email. I think that the fact that you and Antonio have done this pattern before (and I'm sure others have done it too), proves that we may all benefit from a central implementation, so that we can all make it the best possible, instead of going on our own and work on it separately. I think it would also help new users, saving them the time to think about how to achieve this pattern, and also saving them from running into bugs that a central implementation already takes care of. For example, the first implementation I wrote did not have a way to un-register dead comet actors, then I realized this was a bug so I added it. So, do you think it is not worth having it as part of Lift because you already wrote it, or do you see it as something that is just too simple to write on your own? Thanks for your thoughts.
Your implementation and mine are very similar, I do use a syncronize
block which I'm planning on getting rid of, but for the most part we
have the same idea. Now, all those classes are just implementation
details, so, for example, if you wanted to use my library on your next
blog application,you would need:
1- Create a snippet that extends InsertNamedComet, the only three
lines you need in that snippets are:
lazy val cometClass= "BlogEntryDetailCometActor"
val cometName = List(S.locale, blogEntryViewParam.blogEntryId)
lazy val name= cometName.mkString(":")
2- Your cometActor class only needs to extend NamedCometActor, so
there just override lowPriority, mediumPriority or highPriority
3- And whenever you want to send a message to the right CometActor, do
something like this: (note, this is something I want to change)
CometListerner.listenerFor(Full(blogId)) match {
case a: LiftActor => info("Sending msg"); a ! Message("New Text here")
case _ => info("No actor to send an update")
}
So Again, for someone who has not dealt with this situation before, it
is a lot simpler than having to write each of those classes,
remembering to remove dead actors from the register, etc.
Do you see how it is simpler now?
Thanks
Diego
>
> --
> Andreas Joseph Krogh <and...@officenet.no> - mob: +47 909 56 963
> Senior Software Developer / CEO - OfficeNet AS - http://www.officenet.no
> Public key: http://home.officenet.no/~andreak/public_key.asc
>
I'm not sure how the above pattern could be made easier by wrapping it up in a library, but I'm willing to learn of course. Is what I'm doing anything like what you guys are trying to unify into a common library?Your implementation and mine are very similar, I do use a syncronize block which I'm planning on getting rid of, but for the most part we have the same idea. Now, all those classes are just implementation details, so, for example, if you wanted to use my library on your next blog application,you would need: 1- Create a snippet that extends InsertNamedComet, the only three lines you need in that snippets are: lazy val cometClass= "BlogEntryDetailCometActor" val cometName = List(S.locale, blogEntryViewParam.blogEntryId) lazy val name= cometName.mkString(":") 2- Your cometActor class only needs to extend NamedCometActor, so there just override lowPriority, mediumPriority or highPriority 3- And whenever you want to send a message to the right CometActor, do something like this: (note, this is something I want to change) CometListerner.listenerFor(Full(blogId)) match { case a: LiftActor => info("Sending msg"); a ! Message("New Text here") case _ => info("No actor to send an update") }
So Again, for someone who has not dealt with this situation before, it is a lot simpler than having to write each of those classes, remembering to remove dead actors from the register, etc. Do you see how it is simpler now?
You don't send the message to the comet actor, you send it to the
dispatcher liftactor that knows all the cometactors that are showing
the particular blog entry.
>
> Example of updating all comet-actors listening for a blog-entry:
>
> In some code:
>
>
> BlogEntryMasterServer.findServerFor(event.blogEntry.id)
> .foreach(_ ! BlogEntryUpdatedMessage(BlogEntryCometDto(event.blogEntry))
> )
>
> The above is equivalent of (for readability):
>
> val serverForBlogEntry: Option[BlogEntryServer] = BlogEntryMasterServer.findServerFor(event.blogEntry.id)
> serverForBlogEntry.foreach(_ ! BlogEntryUpdatedMessage(event.blogEntry))
>
> So - I send a message to the server serving that blog-entry and all listeners (comet-actors) will get updated by:
>
> override def lowPriority = {
> case m @ BlogEntryUpdatedMessage(blogEntry) =>
> cachedBlogEntry = Full(blogEntry)
> updateListeners(m)
> }
>
> What's the advantage of "manually" sending a message by using CometListerner.listenerFor(Full(blogId)) ?
>
>
>> So Again, for someone who has not dealt with this situation before, it
>> is a lot simpler than having to write each of those classes,
>> remembering to remove dead actors from the register, etc.
>>
>> Do you see how it is simpler now?
>
>
> In my opinion it gets just marginally simpler, but maybe it's worth it.
Hm, was it that dead simple for you to implement the three main parts:
BlogEntryMasterServer
BlogEntryServer
BlogEntryCometActor:
? I know when I asked how to do this a few years ago, David and
another person helped me, but did not just give me all the details of
how to do it, I had to go back and forth a few times, plus I ended up
buying a book on Scala Actors to get the idea of how to write the
dispatcher. I know I was still pretty new to Scala and Lift, but at
that time, it took me a while to get it right.
I think that if we have it as part of Lift, it would make it a lot
easier for users to get the functionality on their apps, we just tell
them to extend from two traits, and only implement their message
handler, as opposed to telling them to implement the register,
dispatcher, make sure to un-register them when they are not accessible
any more, etc.
>
> One argument for having it as part of the library is that then everybody will do it the same way and "the correct way", which make applications consistent and is also easier to communicate to newcommers.
>
> We'd be dictating a naming-convention for comet-actors, which may be good. I often encode stuff like id and locale in the name, separated by colon (':'). I don't know if that will work for all tho...
We don't dictate the naming, users have the freedom to choose the
naming they want. For example, I don't encode the locale when I use
this library, but I used it on this example to match what you had.
Thanks
Diego
>
> --
> Andreas Joseph Krogh <and...@officenet.no> - mob: +47 909 56 963
> Senior Software Developer / CEO - OfficeNet AS - http://www.officenet.no
> Public key: http://home.officenet.no/~andreak/public_key.asc
>
For me it just felt natural to have those 3 parts, each with clear
responsibility.
>> One argument for having it as part of the library is that then everybody will do it the same way and "the correct way", which make applications consistent and is also easier to communicate to newcommers.
>>
>> We'd be dictating a naming-convention for comet-actors, which may be good. I often encode stuff like id and locale in the name, separated by colon (':'). I don't know if that will work for all tho...
> We don't dictate the naming, users have the freedom to choose the
> naming they want. For example, I don't encode the locale when I use
> this library, but I used it on this example to match what you had.
>
> Thanks
>
> Diego
I'm all for code that helps people use provided mechanisms "the right
way". So +1 for making it easier and a part of Lift.
>
>
> I'm all for code that helps people use provided mechanisms "the right way". So +1 for making it easier and a part of Lift.
<phew> , thanks! I hope more people agree during the next few days.
Diego
Hi,
Short version:
Would you find it useful if I added my named comet actor per browser
tab[1] to Lift 2.5?
[1] http://blog.fmpwizard.com/lift-comet-actor-per-tab-library
--
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
Thanks
Diego
Hi. Sorry to bother you, but Is this part of liftweb yet?
--
--
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
---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.