0

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!

S.O.S
  • 848
  • 10
  • 30

1 Answers1

0

First of all i would recommend you to make a thread dump in order to find an exact place which is hang. In meantime try to look at source code of library you use trying to understand what could cause this hanging. Most likely the library invokes something which is not responsible for interruption. Luckily there are not so many such operations and most of them are related to socket I/O. The most comprehensive list i've ever seen for JDK is present in "Java Concurrency in Practice" book chapter 7.1.6. Socket I/O looks like a reasonable explanation for your case because client library for sure invokes ebay API via HTTP. If it uses standard JDK HTTP client try to set these timeouts. Otherwise the only possible solution is to change source code of the library to make it responsible to interruption or use another one :)

Mikita Harbacheuski
  • 2,193
  • 8
  • 16