-
Bug
-
Resolution: Done
-
Critical
-
3.0.7.Final
-
Compatibility/Configuration, User Experience
There's a problem managing StreamingOutput, it seems it's not thread safe and cannot be paralleled, if I call the StreamingOutput that streams a big file for example, until the service is done streaming the file, no other user can call the Resource serving the files.
Is there a way around this? that way many users can download big files.
I use StreamingOutput to output the file because if not, then the file gets all loaded into RAM effectively killing the application, so streaming files avoids loading the whole file into memory.
Here's a code sample of the Resource method I use for streaming the file output, I'm using my OpenSuSE ISO file which is 4.7GB so I can test big file buffering:
@GET @Produces(MediaType.APPLICATION_OCTET_STREAM) @Path("getFile") public Response getFile() throws FileNotFoundException { final FileInputStream file = new FileInputStream("/home/documents/openSUSE-13.1-DVD-x86_64.iso"); StreamingOutput stream = new StreamingOutput() { @Override public void write(OutputStream out) throws IOException, WebApplicationException { //buffer size set to 10MB int bufferSize = 1024 * 1024 * 10; int buffer = 1; int rs = file.read(); while (rs != -1) { out.write(rs); rs = file.read(); buffer++; //flush the output stream every 10MB if (buffer == bufferSize) { buffer = 1; out.flush(); } } out.flush(); } }; return Response.ok(stream).header("Content-Disposition", "attachment; filename=\"openSUSE-13.1-DVD-x86_64.iso\"").build(); }
I tested this Resource using JBoss WildFly 8.1.0, but if using resteasy-netty4 for serving this resource, the problem is even bigger, all file downloads get frozen and then suddenly the output is flushed to RAM and the java process grows out filling the heap killing the application.
Mind me saying that even though I tested WildFly, that was just to make sure it wasn't a problem with the netty4 adapter, but I'm using resteasy-netty4, so if someone knows a workaround using netty4 then great! I've seen things in the resteasy-netty4 source like ChunkedOutputStream but I don't even know where to start figuring out a workaround to this issue.