[
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]