Question

I am using Spray 1.3, with incoming-auto-chunking-threshold-size set, to allow streaming of incoming requests.

When a very large request comes in from my client, I want to stream it through the app and out to a backing store in chunks, to limit the memory used by the Spray app.

I am finding that Spray will slurp in the response as fast as it can, creating MessageChunks of the configured size and passing them to my app.

If the backend store is slow, then this results in Spray caching most of the request in local memory, defeating the streaming design.

Is there any way I can get Spray to block or throttle the request stream so that the input data rate matches the output data rate, to cap my app's memory usage?

Relevant spray code:

The HttpMessagePartParser.parseBodyWithAutoChunking method is the one which breaks up the request byte stream into MessageChunk objects. It does so greedily, consuming as many chunks as are immediately available, then returning a NeedMoreData object.

The request pipeline accepts NeedMoreData in the handleParsingResult method of the RawPipelineStage, with the following code:

case Result.NeedMoreData(next) ⇒ parser = next // wait for the next packet

... so it looks to me like there is no "pull" control of the chunking stream in Spray, and the framework will always read in the request as fast as it can manage, and push it out to the app's Actors as MessageChunks. Once a MessageChunk message is in the queue for my Actor, its memory can't be cached to disk.

So there is no way to limit the memory used by Spray for a request?

Was it helpful?

Solution

There is a workaround discussed here: https://github.com/spray/spray/issues/281#issuecomment-40455433

This may be addressed in a future spray release.

EDIT: Spray is now Akka HTTP, which has "Reactive Streams" which gives back-pressure to the TCP stream while still being async: https://groups.google.com/forum/#!msg/akka-dev/PPleJEfI5sM/FbeptEYlicoJ

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top