For anyone else interested in this topic, here are a few more things I
found:
** When I created a no-arg upload method (to avoid Play trying to
buffer and bind/instantiate objects for me) memory usage for
processing an HTTP POST of an 8 MB image went from spiking the Play
java process from 90mb to 520mb (my heap) to bouncing it from 90 to
about 92mb.
This was interesting to me because it suggested that in the previous
impl, Play seems to be trying to keep the form args all in memory as
it processes them where as with the no-arg method, they primarily stay
in the stream until processed (exactly what I want, even if it takes a
bit longer to buffer them out of the stream).
** (For folks messing with FileAPI/DataURI business) I found that
setting headers in my ajax call with the file name, size and type and
then using very simple String concat on the client side Javascript
allowed me to keep the actual *body* of my post dead-simple and only
contain the base64 content as opposed to a query string containing all
args and then a Data-URI formatted string ("data:image/
jpeg;base64,jSDkjasLksd...")
I liked this because it simplifies the Play controller code and
offloads the minor String operations onto the client instead of me
chopping things up on the server side wasting time.
Minor, but it also allowed me to do some quick sanity checking on the
client side before sending the data (like making sure it is a dataURI
format, it is long enough to be valid, etc.) so by the time things get
to the server, all I need is a null/empty check and I'm off to the
races as far as processing goes.
TIP: For those trying to do something similar, take a look at this
Base 64 encoding lib:
http://iharder.sourceforge.net/current/java/base64/
It's been around for a while and consistently worked on, I also
replaced commons-codec in a project recently (4sq checkin hack) that
hung consistently for about half my users when calling into the
Commons Codec Base64 class for whatever reason (I've also encountered
encoding/decoding bugs with the MigBase64 encoding lib)... anyone one
of the nicest features about the one linked above is it provides
convenience methods for decoding/encoding to and from Files directly
with a small interm buffer or even better yet (for my case) customized
Input/Output streams that can encode/decode directly.
That should allow me to take the request.body InputStream from Play
and run it right through a decoder straight out a file, keeping memory
usage low and then fire off a background AWS S3 upload.
It really feels like things are coming together and I just wanted to
share for anyone else that might run across this in the future and
feel overwhelmed.
Best,
Riyad