dev@grizzly.java.net

Re: Question for processing multipart

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Fri, 22 Jan 2016 20:58:01 -0800

Hi Bongjae,


On 1/22/16 1:11 AM, Bongjae Chang wrote:
>
> 1. How to stop/cancel processing multipart forcefully or how to
> process multipart synchronously(blocking mode).
>
> org.glassfish.grizzly.samples.httpmultipart.UploaderHttpHandler uses
> MultipartScanner#scan and the response will be resumed at the
> CompletionHandler when all processing will be done(success or failure).
>
> Some multipart's content can be too large or some processing can be
> too delayed so I could stop the process forcefully. ex) applying timeout.
>
> My first idea was below:
>
> --
> response.suspend();
>
> MultipartScanner.scan(request, uploader, new EmptyCompetionHandler() {
> public void completed(Request request) {
> ...
> // response.resume();
> latch.countDown();
> }
>
> public void failed(Throwable t) {
> ...
> // response.resume();
> latch.countDown();
> }
>
> public void cancelled() {
> ...
> latch.countDown();
> }
> }));
>
> latch.await(timeout, ...);
> // timed out or completed
> ...
> response.resume();
> --
>
> But when timed out, I met some NPEs because request/response was
> recycled in service thread and multipart thread had old refereces
> which were already reset.
You see NPE in the MultiPart thread once you call response.resume in the
service thread, is that correct?
If yes - it's expected, Response.resume() resets the request/response
objects, so if there is a thread, that reads/writes using these
request/response objects - it will fail.
As a work around you may try to close the connection on timeout in the
service thread and wait for the latch.

> 2. When I debugged org.glassfish.grizzly.http.server.Request#recycle()
> and
> org.glassfish.grizzly.http.HttpServerFilter$ServerHttpRequestImpl#recycle(),
> I saw ServerHttpRequestImpl's instance was not reset because
> isExpectContent() was true.
>
> In this case, the calling flow was below:
>
> org.glassfish.grizzly.http.server.HttpServerFilter#afterService() ->
> org.glassfish.grizzly.http.server.Request#recycle() ->
> org.glassfish.grizzly.http.HttpServerFilter$ServerHttpRequestImpl#recycle()
> I would like to know it was the intended purpose in above flow because
> org.glassfish.grizzly.http.server.Request instance was cleared but
> it's ServerHttpRequestImpl instance was not cleared.
My guess is that this is done to have enough information/context to skip
the HTTP request remainder (because we still expect content for the
current request) and prepare to read next request on this connection.

Thank you.

WBR,
Alexey.


>
> Thanks!
>
> Regards,
> Bongjae Chang
>