Question for processing multipart

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Question for processing multipart

Bongjae Chang
Hi,

I have two questions.

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.


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.

Thanks!

Regards,
Bongjae Chang

Reply | Threaded
Open this post in threaded view
|

Re: Question for processing multipart

oleksiys
Administrator
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


Reply | Threaded
Open this post in threaded view
|

Re: Question for processing multipart

Bongjae Chang
Hi Alexey,

Right. I will try to do a work around.

Thanks!

On Sat, Jan 23, 2016 at 1:58 PM, Oleksiy Stashok <[hidden email]> wrote:
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