My application relies on eBay Picture Service to upload images to from my desktop to eBay server. Normally, it takes a few seconds for the upload to complete. However, it can sometimes take hours, and occasionally, it may never complete. It is unpredictable when this will happen and no exception is thrown by API. This causes my application to call external API too many times simultaneously and also hogs system resources.
My goal is to set a timeout for upload and cancel underlying process if upload is not successful within time limit. I tried to set a timeout on ExecutorService
and then cancel future
when an exception is thrown as suggested in this and this post:
ExecutorService executorService = Executors.newFixedThreadPool(10);
ArrayList<Future<?>> futuresList = new ArrayList<Future<?>>();
for (String singleTask : taskList) {
futuresList.add(executorService.submit( new Runnable(){
@Override
public void run(){
try {
myBlockingTask(singleTask);
} catch (IOException | InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}));
}
try {
future.get(240, TimeUnit.SECONDS);
} catch (Exception e){
e.printStackTrace();
// Stops parent thread from waiting for child but it does not terminate 'child' thread.
// As a result, call(s) to external API continue to increase (rapidly) since the underlying process never actually ends
future.cancel(true);
}
Unfortunately, this solution only works when the underlying thread keeps running due to an infinite loop and/or the underlying operation is designed to understand Thread.isInterrupted()
(like in a while()
loop). In this case, however, I have no control over the underlying process so it is not possible for me to call interrupt in the child thread. The API does not provide a timeout method either.
Is there any way to force blocking operation to terminate in this example?
Thanks!