Lift HandledRoundTrip and closed connection

20 views
Skip to first unread message

Jason Mack

unread,
Jul 13, 2017, 11:15:17 AM7/13/17
to Lift
Currently with a handled round trip in lift 3.0.0(and in the latest master) there isn't any reasonable way to tell when a client has disconnected. Is there any chance of getting the current actor state passed through? That would be nice for cases where data needs to be streamed until the client disconnects.

Matt Farmer

unread,
Jul 13, 2017, 11:26:48 AM7/13/17
to Lift
Hey Jason,

Thanks for reaching out. I'm not _quite_ sure what you're asking for based on the email alone. Can you give me a little bit more context about your use case?

Thanks!

On Thu, Jul 13, 2017 at 11:15 AM Jason Mack <jmac...@gmail.com> wrote:
Currently with a handled round trip in lift 3.0.0(and in the latest master) there isn't any reasonable way to tell when a client has disconnected. Is there any chance of getting the current actor state passed through? That would be nice for cases where data needs to be streamed until the client disconnects.

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

Jason Mack

unread,
Jul 13, 2017, 11:55:16 AM7/13/17
to Lift
I am including some of the code below as an explanation:

def fetchData(t: JValue, func: RoundTripHandlerFunc): Unit = {
 def stream: scala.collection.immutable.Stream[Call] = Call("console.log", 1) #:: stream

  val iter = stream.iterator

  def send(): Unit = {
   func.send(iter.next())
   send()
 }

  send()
}

def getFunctions(in: NodeSeq): NodeSeq = {
 for (session <- S.session) {
   val script =
     JsCrVar(
       "customLiftFunctions",
       session.buildRoundtrip(
         List(
           HandledRoundTrip("fetchData", fetchData)
         )
       )
     )
   S.appendGlobalJs(script)
 }
 in
}

getFunctions is included with:

<div data-lift="MySnippet.getFunctions"></div>

I am aware there is already a helper for scala.collection.immutable.Stream, but the actual implementation spawns  worker threads. The issue is that there isn't a great way to tell that the user has disconnected(via closing the browser tab). The current implementation for this capability appears to use a comet actor to send messages down to the client(LiftSession#2674 on master). Would there be any chance of a method being provided that would tell when that CometActor has stopped running due to a timeout? The normal timeout for CometActors is more than sufficient for my use case.

Matt Farmer

unread,
Jul 13, 2017, 12:15:28 PM7/13/17
to Lift
Got it. This makes sense.

I think what you want here is to attach a session shutdown hook. The comet actor you mention is the heartbeat for this session. Lift sessions expire after a configurable timeout (20 minutes, by default) and after that any resources associated with them should be freed by a series of shutdown functions. (That goes for our helpers, as well, but if that isn't the case we should fix that bug.) You can attach your own function to LiftSession.onShutdownSession to run some code every time a session is shut down.

The best way to do this would depend on your implementation, but you could define your own session resource registry of sorts. So, for example, it could be something like this:

Once again, the exact mechanics of this would depend on the details of your implementation, but the above would generically work for open files and thread pools, I believe.

Let me know if this doesn't answer your question. =)

Cheers,
Matt

Matt Farmer

unread,
Jul 13, 2017, 12:16:26 PM7/13/17
to Lift
Oh, I almost forgot. With the gist I linked to above, you'd need to add the onSessionShutdown function to the list in LiftSession.onShutdownSession from your Boot.scala file.

Jason Mack

unread,
Jul 13, 2017, 12:44:27 PM7/13/17
to Lift
I did try something earlier like this, 

val session: LiftSession = ???
val stop: scalaz.concurrent.Task[Unit] = ???
session.addSessionCleanup { _ =>
  stop.unsafePerformAsync(_.leftMap(t => logger.error(s"Failed to stop $name on $sessionId.", t)))
}

If this wasn't being called, is there some reason I should expect the above to work instead? It is possible I am doing something to keep the session alive and not realizing it. I waited 10+ minutes beyond the current timeout in our configuration and that never was called.

Matt Farmer

unread,
Jul 13, 2017, 1:01:32 PM7/13/17
to Lift
Hmmm. It's possible that session shutdown and session cleanup are two distinct events, but I would need to reacquaint myself with the code to be sure. I can probably follow up in the next day or so and let you know if you like.

Antonio Salazar Cardozo

unread,
Jul 18, 2017, 11:21:52 AM7/18/17
to Lift
Took me a minute to find it, but I believe this is what #1821 is about. I think
the basic mechanism is just a parameter on `buildRoundTrip` that is a function
executed in the returned comet actor's `localShutdown`.
Thanks,
Antonio
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+unsubscribe@googlegroups.com.

Jason Mack

unread,
Jul 18, 2017, 11:24:12 AM7/18/17
to lif...@googlegroups.com
Ah, thanks, that is exactly what I would want. Thanks for pointing that out.

You received this message because you are subscribed to a topic in the Google Groups "Lift" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/liftweb/X4YFBW9NGD8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to liftweb+unsubscribe@googlegroups.com.

Matt Farmer

unread,
Jul 18, 2017, 11:47:18 AM7/18/17
to lif...@googlegroups.com
Thanks for responding to this Antonio. I spent all weekend fighting with my blog and didn't get around to investigating this 💀
You received this message because you are subscribed to a topic in the Google Groups "Lift" group.
To unsubscribe from this group and all its topics, send an email to liftweb+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages