Chunk streaming response doesn't get PeerClosed on browser cancellation

Skip to first unread message

Ryan O'Rourke

Dec 6, 2017, 8:12:11 PM12/6/17
to User List
Hi, running Spray version 1.1.1.

I've implemented an actor to handle chunked streaming responses. It works for the most part, but I'm having trouble catching when the remote side closes the connection. 

Here's some code from my actor's receive method:

    case ev: Http.ConnectionClosed =>
      emitMetrics(failure = Some(ev.toString))
      log.warn("Stopping response streaming due to {}", ev)

    case ev: Http.CloseCommand =>
      emitMetrics(failure = Some(ev.event.toString))
      log.warn("Stopping response streaming due to {}", ev)

If I make the request using curl and then kill it with ctrl-C while streaming, the actor gets a PeerClosed message which is picked up by the above code. It closes things down and everything is good.

However, if I make the request from a browser (specifically, from an <a> element with an href pointing at the Spray server, and a download disposition) and then cancel the in-progress download, the actor doesn't get any notification. It continues pulling data and trying to send it. Eventually it does emit an error to the log file: "Could not write response part MessageChunk, aborting connection". Even then, it doesn't seem to send a message to the actor, though that's a little unclear (I'm seeing the receive timeout firing in my actor hot on the heels of that error message).

I'd really like to be able to stop querying the datasource if a user cancels the streaming download... is there another message I should listen for? Is this just browser behavior I can't control?

Ryan O'Rourke

Dec 8, 2017, 5:50:35 PM12/8/17
to User List
More info: I rolled this implementation to production, and there I see the desired behavior - PeerClosed messages are getting sent to and caught by my actor.

So, curl vs. browser may be a red herring. Probably the difference is that in the testing scenario we were running an angular app on a workstation talking directly to a (co-located) instance of the Spray server, while in production the requests from Angular are routed through Apache and also a VIP. So probably has nothing to do with Spray.

For my own enlightenment I'd still love to hear a solid explanation rather than my vague suspicions.

Age Mooij

Dec 10, 2017, 10:22:47 AM12/10/17
to User List
Hi Ryan

As you might be aware, Spray has officially been replaced by Akka Http, which supports all of the original Spray features but with better performance, many bug fixes, an active supporting community, and regular updates.

This happened several years ago and at this point Spray is no longer actively maintained.
The last official Spray releases are from March 2015 and the final version released was 1.3.3. 
The 1.1.x branch requires versions of Akka, Scala, and the JVM that are no longer maintained or supported.
I would strongly advise you to switch to using Akka Http

Reply all
Reply to author
0 new messages