Would you like to see this in Lift 2.5?

276 views
Skip to first unread message

Diego Medina

unread,
Mar 24, 2012, 12:57:20 AM3/24/12
to Lift
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


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

AGYNAMIX Torsten Uhlmann

unread,
Mar 24, 2012, 4:40:37 AM3/24/12
to lif...@googlegroups.com
It sounds like a great addition. I remember you worked with David to find a good solution, and it also seems to be already used in several projects, which speaks for the stability of the code.

Now, is there any implication that you wrote the code before you signed the IP contract?

It's a pleasure to read your insightful posts!

Torsten.

-- 
AGYNAMIX(R). Passionate Software.
Inh. Torsten Uhlmann | Buchenweg 5 | 09380 Thalheim
Phone:       +49 3721 273445
Fax:             +49 3721 273446
Mobile:       +49 151 12412427
Web:           http://www.agynamix.de

Antonio Salazar Cardozo

unread,
Mar 24, 2012, 10:06:46 AM3/24/12
to lif...@googlegroups.com
I confess I haven't looked at your project in depth, but isn't what you're describing already doable by just the CometActor's name parameter and LiftSession.sendCometActorMessage with the name specified? Or is the distinction here that you can have multiple CometActor's with the same “name”, which if you were using CometActor's built-in name stuff would not be possible?
Thanks,
Antonio

Diego Medina

unread,
Mar 24, 2012, 10:48:25 AM3/24/12
to lif...@googlegroups.com

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

--

Diego Medina

unread,
Mar 24, 2012, 10:49:21 AM3/24/12
to lif...@googlegroups.com

Thanks Torsten.

Diego
Sent from my android cell

Antonio Salazar Cardozo

unread,
Mar 24, 2012, 11:00:47 AM3/24/12
to lif...@googlegroups.com
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.

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.
Thanks,
Antonio

Diego Medina

unread,
Mar 24, 2012, 1:15:16 PM3/24/12
to lif...@googlegroups.com

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

Antonio Salazar Cardozo

unread,
Mar 24, 2012, 3:20:54 PM3/24/12
to lif...@googlegroups.com

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.

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 

Diego Medina

unread,
Mar 24, 2012, 5:51:32 PM3/24/12
to lif...@googlegroups.com


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 
>

Andreas Joseph Krogh

unread,
Mar 25, 2012, 4:20:04 AM3/25/12
to lif...@googlegroups.com

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

Diego Medina

unread,
Mar 25, 2012, 10:07:38 AM3/25/12
to lif...@googlegroups.com
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.

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

--

Andreas Joseph Krogh

unread,
Mar 25, 2012, 4:41:18 PM3/25/12
to lif...@googlegroups.com
On 03/25/2012 04:07 PM, Diego Medina wrote:
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.

Ok, let me start with what I usually do. I use viewing a blog-entry (uri=/blog/1 for blog-entry with id=1) as an example.

I have 3 central parts:
  • BlogEntryMasterServer
    • A singleton acting as a registry
  • BlogEntryServer
    • The server which the comet-actor calls "registerWith" on
    • one server for each entity (id) which is being viewed
  • BlogEntryCometActor: The comet-actor showing the blog-entry
    • This comet-actor has the id of the blog-entry as part of its name so many instances of it exists, but with different name, depending on which blog-entry the user is viewing

Here are the central parts of the code I'm using:

object BlogEntryMasterServer extends LiftActor with Loggable {

    private val serverMap = new HashMap[Long, BlogEntryServer]()

    def findServerFor(blogEntryId: Long): Option[BlogEntryServer] = {
        serverMap.get(blogEntryId)
    }

    // Using "send-and-wait-for-reply" we don't need to worry about synchronizing serverMap
    def registerWithServer(blogEntryId: Long): BlogEntryServer = {
        (this !! RegisterServerMessage(blogEntryId)).open_!.asInstanceOf[BlogEntryServer]
    }

    protected def messageHandler = {
        case RegisterServerMessage(entityId) =>
            val server = serverMap.getOrElseUpdate(entityId, new BlogEntryServer(entityId))
            reply(server)
        case ServerListenersListEmptiedMessage(Some(entityId), _) =>
            serverMap.remove(entityId)
            reply("Removed server: " + entityId + " from registry of server")
    }

}

class BlogEntryServer(val blogEntryId: Long) extends LiftActor with ListenerManager {
    private var cachedBlogEntry: Box[BlogEntryCometDto] = Empty

    override def createUpdate = {
        if (!cachedBlogEntry.isDefined) {
            cachedBlogEntry = Full(BlogEntryCometDto(blogEntryService.retrieve(blogEntryId)))
        }
        BlogEntryServerCreatedMessage(cachedBlogEntry, voteMap)
    }

    // Send message to de-register this server
    override protected def onListenersListEmptied() {
        BlogEntryMasterServer !! ServerListenersListEmptiedMessage(blogEntryId)
    }
}

class BlogEntryDetailCometActor extends CometActor with CometListener  {
    lazy val nameParts = name.open_!.split(":")
    lazy val blogEntryIdent = nameParts(1).toLong
    protected def registerWith = BlogEntryMasterServer.registerWithServer(blogEntryIdent)
}


Using the above pattern registering a new server and removing it (it's important to remove servers which have no comet-actors subscribed to avoid ever-growing maps of servers in the registry) all happens in the registry-singleton's message-handler, so no synchronization is needed.

Then I create all comet-actors using this pattern:

val cometName = List(S.locale, blogEntryViewParam.blogEntryId)
<div class={"lift:comet?type=BlogEntryDetailCometActor;name="+cometName.mkString(":")}
    style="display: inline;">
    {ns}
</div>

So the name is here "no:1", where "no" is the locale and "1" is the id of the blog-entry.

I use domain-events to signal a BlogEntryServer that a blog-entry has been updated like this:

BlogEntryMasterServer.findServerFor(event.blogEntry.id)
    .foreach(_ ! BlogEntryUpdatedMessage(BlogEntryCometDto(event.blogEntry))
)


Note that findServerFor() is a read-only operation and doesn't need to worry about concurrency issues in BlogMasterServer, hence it accesses the registry-map directly instead of sending a message to itself, like registerWithServer() needs to.

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?

Diego Medina

unread,
Mar 25, 2012, 6:49:38 PM3/25/12
to lif...@googlegroups.com
> 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?

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
>

Andreas Joseph Krogh

unread,
Mar 26, 2012, 3:50:02 AM3/26/12
to lif...@googlegroups.com
On 03/26/2012 12:49 AM, Diego Medina wrote:
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")
}

I'm not sure I follow you on this last part. Why would you want to send a message to a Comet-actor and not to the server which it is registered with, like in my case BlogEntryServer. Note that I have a server (LiftActor with ListenerManager) for each blog-entry, and a master-server (LiftActor to be able to send messages to it) to keep a registry of servers. By sending the message to the server and have it call "updateListeners" makes it update all comet-actors listening, which may be many users viewing the same blog-entry and all need to get updated with the new post, or is this not what you want?

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.

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

Diego Medina

unread,
Mar 27, 2012, 1:16:33 AM3/27/12
to lif...@googlegroups.com
On Mar 26, 2012 3:50 AM, "Andreas Joseph Krogh" <and...@officenet.no> wrote:
>
> On 03/26/2012 12:49 AM, Diego Medina wrote:
>>>
>>> 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")
>> }
>
>
> I'm not sure I follow you on this last part. Why would you want to send a message to a Comet-actor and not to the server which it is registered with, like in my case BlogEntryServer. Note that I have a server (LiftActor with ListenerManager) for each blog-entry, and a master-server (LiftActor to be able to send messages to it) to keep a registry of servers. By sending the message to the server and have it call "updateListeners" makes it update all comet-actors listening, which may be many users viewing the same blog-entry and all need to get updated with the new post, or is this not what you want?

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
>

Andreas Joseph Krogh

unread,
Mar 27, 2012, 2:49:57 AM3/27/12
to lif...@googlegroups.com

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.

Diego Medina

unread,
Mar 27, 2012, 3:30:58 AM3/27/12
to lif...@googlegroups.com

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

David Pollak

unread,
Apr 6, 2012, 4:43:35 PM4/6/12
to lif...@googlegroups.com
On Fri, Mar 23, 2012 at 9:57 PM, Diego Medina <di...@fmpwizard.com> wrote:
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

Looks very cool!
 
--
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


Diego Medina

unread,
Apr 6, 2012, 10:03:12 PM4/6/12
to lif...@googlegroups.com
Thanks everyone, I'll be working on this real soon.
And I have some thoughts on how to support comet communication across
several Lift servers. As in having a chat room where someone connects
to a server in the US and talks to someone else connected to a server
in Asia.
But that will be a separate post.

Thanks

Diego

Bhashit Parikh

unread,
Jul 8, 2016, 5:53:36 AM7/8/16
to Lift
Hi. Sorry to bother you, but Is this part of liftweb yet?

ari gold

unread,
Jul 8, 2016, 6:59:13 PM7/8/16
to Lift
I'm not sure if this is exactly what you're looking for but there was recent thread about comet communication that might help:
https://groups.google.com/forum/#!searchin/liftweb/piotr/liftweb/HYyKtUOi_og/Ovdc3bKdBgAJ

For now, the work appears to be released as a module:
https://oss.sonatype.org/content/repositories/releases/net/liftmodules/messagebus_3.0_2.11/

'course how to use modules is another thing altogether:
http://liftweb.net/lift_modules

Diego Medina

unread,
Jul 10, 2016, 3:41:17 PM7/10/16
to Lift
On Fri, Jul 8, 2016 at 5:53 AM, Bhashit Parikh <bhashit...@gmail.com> wrote:
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.



--
Diego Medina
Lift/Scala Consultant
di...@fmpwizard.com
http://blog.fmpwizard.com/
Reply all
Reply to author
Forward
0 new messages