[ 
http://issues.apache.org/jira/browse/HTTPCLIENT-596?page=comments#action_12426670
 ] 
            
Arnaud Masson commented on HTTPCLIENT-596:
------------------------------------------

Hello Roland

I have found two methods to fix this problem:

1) Use NIO. I don't know well this API but since SocketChannel inherits from 
InterruptibleChannel, it must provide some mechanism to cancel a network 
transfer.

2) Execute all non-cancelable operations is a separate thread (or in an 
Executor) so that the working thread waits on a "join()" which supports 
Thread.interrupt().
For instance, the non-cancelable stream can be wrapped in a proxy stream that 
looks like:
-------
public class CancelableInputStream extends InputStream {

    
    private InputStream mDelegate;
    private ExecutorService mThreadPool;
    
    
    public CancelableInputStream(InputStream delegate) {
        
        mDelegate = delegate;
        mThreadPool = Executors.newFixedThreadPool(
                2,
                ProcessingUtils.getThreadFactory(
                        "CancelableInputStream " + delegate)
        );
    }
    
    
    @Override
    public int read() throws IOException {
        
        Callable<Integer> c = new Callable<Integer>() {
            public Integer call() throws IOException {          
                return mDelegate.read();
            }           
        };
        
        return callInSeparateThread(c);       
    }


    @Override
    public int read(final byte[] b, final int off, final int len) throws 
IOException {

        Callable<Integer> c = new Callable<Integer>() {
            public Integer call() throws IOException {          
                return mDelegate.read(b, off, len);
            }           
        };
        
        return callInSeparateThread(c);
    }


    @Override
    public int read(final byte[] b) throws IOException {
        
        Callable<Integer> c = new Callable<Integer>() {
            public Integer call() throws IOException {          
                return mDelegate.read(b);
            }           
        };
        
        return callInSeparateThread(c);
    }

    
    @Override
    public void close() throws IOException {
       
        mDelegate.close();
        mThreadPool.shutdownNow();
    }


    private <T> T callInSeparateThread(Callable<T> r) throws IOException {
        
        try {
            
             Future<T> f = mThreadPool.submit(r);
             return f.get(); // does a join()          
        }
        catch (InterruptedException ie) {
            
            throw CoreUtils.wrapIOException(ie);          
        }
        catch (ExecutionException e) {
            
            throw CoreUtils.wrapIOException(e.getCause());
        }
    }

}
-------

(I have tested only #2)

Thanks for your help!

> read() on the stream returned by HttpMethod.getResponseBodyAsStream() cannot 
> be simply canceled with Thread.interrupt
> ---------------------------------------------------------------------------------------------------------------------
>
>                 Key: HTTPCLIENT-596
>                 URL: http://issues.apache.org/jira/browse/HTTPCLIENT-596
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpClient
>    Affects Versions: 3.0 Final, 3.0.1
>         Environment: Windows XP
>            Reporter: Arnaud Masson
>
> I have a working thread that needs to download some big file with 
> HttpMethod.getResponseBodyAsStream().
> A swing component displays a progress indication and has a "stop" button.
> When the stop button is clicked by the user, I would like to stop the 
> download as soon as possible, so I call interrupt() on the working thread 
> from the EDT, which should throw an InterruptedException or 
> InterruptedIOException inside the working thread.
> But the read() operation on the stream returned by 
> HttpMethod.getResponseBodyAsStream() is not interrupted.
> The working thread stacktrace is:
>       SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int)  
> //<--------- blocking
>       SocketInputStream.read(byte[], int, int) line: 129      
>       BufferedInputStream.fill() line: 218    
>       BufferedInputStream.read() line: 235    
>       ChunkedInputStream.getChunkSizeFromInputStream(InputStream) line: 249   
>       ChunkedInputStream.nextChunk() line: 220        
>       ChunkedInputStream.read(byte[], int, int) line: 175     
>       AutoCloseInputStream(FilterInputStream).read(byte[], int, int) line: 
> 111        
>       AutoCloseInputStream.read(byte[], int, int) line: 107   
>       ...
> I know that  the JRE SocketInputStream doesn't support interrupt() but 
> HttpClient should hide this problem.
> A workaround is to use request.abort() but it should be possible to cancel a 
> thread without knowing on what it is blocked.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to