/**
   * All the search requests are sent out in parallel.... wait for all of them to be done. This
   * method can be called as-is from a waiter thread with push ...that is if the push can work more
   * reliably.
   */
  private void waitForSearchResults(PatientSearchCompletionService completionService) {
    try {
      System.out.println("#################" + completionService.getNodesToSearch().size());
      List<NBIANode> noResponseNode = new ArrayList<NBIANode>();
      for (NBIANode node : completionService.getNodesToSearch()) {
        noResponseNode.add(node);
      }
      for (int i = 0; i < completionService.getNodesToSearch().size(); i++) {
        try {
          // this is a blocking call
          Future<PatientSearchResults> future =
              completionService
                  .getCompletionService()
                  .poll(NCIAConfig.getTimeoutInMin(), TimeUnit.MINUTES);
          //	this is a blocking call
          PatientSearchResults result = null;
          if (future != null) {
            result = future.get();
            System.out.println(
                "got response from node " + result.getNode().getDisplayName() + " so remove it");
            noResponseNode.remove(result.getNode()); // got response so remove it
            logResult(result);
            addNodeResult(result);
          }
        } catch (CancellationException e) {
          e.printStackTrace();
        }

        // pushToBrowser();
      }
      if (noResponseNode != null && !noResponseNode.isEmpty()) {
        //	check is there are any node from where, no response came with configurable minutes.
        for (NBIANode node : noResponseNode) {
          System.out.println("no response Node" + node.getDisplayName());
          Exception searchError = new Exception("no response from node");
          PatientSearchResults result = new PatientSearchResults(node, searchError);
          logResult(result);
          addNodeResult(result);
        }
      }

      System.out.println("done waiting for results");
    }
    //		catch(InterruptedException ie) {
    //			System.out.println("interrupted the async result waiter");
    //		}
    catch (Exception ex) {
      // shouldnt get here, the search result service should capture
      // any exceptions and results a search result that indicates
      // there was an error
      ex.printStackTrace();
    }
  }
 private AlgoResponse pipeRequest(String input, ContentType content_type) throws APIException {
   try {
     return pipeRequestAsync(input, content_type).get();
   } catch (java.util.concurrent.ExecutionException e) {
     throw new APIException(e.getCause().getMessage());
   } catch (java.util.concurrent.CancellationException e) {
     throw new APIException(
         "API connection cancelled: " + algoRef.getUrl() + " (" + e.getMessage() + ")", e);
   } catch (java.lang.InterruptedException e) {
     throw new APIException(
         "API connection interrupted: " + algoRef.getUrl() + " (" + e.getMessage() + ")", e);
   }
 }
 /** @see javax.swing.SwingWorker#done() */
 @Override
 protected void done() {
   try {
     Map<SignatureType, SignatureFileInfo> updatedFiles = get();
     progressDialog.setVisible(false);
     DialogUtils.showUpdateSuccessfulDialog(parent, updatedFiles);
   } catch (InterruptedException e) {
     log.debug(e);
   } catch (ExecutionException e) {
     log.error(e.getCause(), e);
     progressDialog.setVisible(false);
     DialogUtils.showSignatureUpdateErrorDialog(parent, e.getCause());
   } catch (CancellationException e) {
     log.warn(e.getMessage());
   } finally {
     progressDialog.setVisible(false);
     progressDialog.dispose();
     parent.setCursor(Cursor.getDefaultCursor());
   }
 }
  /**
   * @param files
   * @return
   * @throws PMDException
   */
  public static Map<String, IPackage> computeAsts(final Map<String, IFlexFile> files)
      throws PMDException {
    final Map<String, IPackage> asts = new LinkedHashMap<String, IPackage>();

    for (final Entry<String, IFlexFile> fileEntry : files.entrySet()) {
      final IFlexFile file = fileEntry.getValue();

      try {
        final IParserNode node = buildThreadedAst(file);

        asts.put(file.getFullyQualifiedName(), NodeFactory.createPackage(node));
      } catch (final InterruptedException e) {
        LOGGER.warning(buildLogMessage(file, e.getMessage()));
      } catch (final NoClassDefFoundError e) {
        LOGGER.warning(buildLogMessage(file, e.getMessage()));
      } catch (final ExecutionException e) {
        LOGGER.warning(buildLogMessage(file, e.getMessage()));
      } catch (final CancellationException e) {
        LOGGER.warning(buildLogMessage(file, e.getMessage()));
      }
    }
    return asts;
  }
    private FactoryManager getApplicationFactoryManager(ClassLoader cl) {

      while (true) {
        Future<FactoryManager> factories = applicationMap.get(cl);
        if (factories == null) {
          Callable<FactoryManager> callable =
              new Callable<FactoryManager>() {
                public FactoryManager call() throws Exception {
                  return new FactoryManager();
                }
              };

          FutureTask<FactoryManager> ft = new FutureTask<FactoryManager>(callable);
          factories = applicationMap.putIfAbsent(cl, ft);
          if (factories == null) {
            factories = ft;
            ft.run();
          }
        }

        try {
          return factories.get();
        } catch (CancellationException ce) {
          if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.log(Level.FINEST, ce.toString(), ce);
          }
          applicationMap.remove(cl);
        } catch (InterruptedException ie) {
          if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.log(Level.FINEST, ie.toString(), ie);
          }
          applicationMap.remove(cl);
        } catch (ExecutionException ee) {
          throw new FacesException(ee);
        }
      }
    }
  @Override
  public Result[] call(int timeout) throws IOException {
    // If the active replica callable was closed somewhere, invoke the RPC to
    // really close it. In the case of regular scanners, this applies. We make couple
    // of RPCs to a RegionServer, and when that region is exhausted, we set
    // the closed flag. Then an RPC is required to actually close the scanner.
    if (currentScannerCallable != null && currentScannerCallable.closed) {
      // For closing we target that exact scanner (and not do replica fallback like in
      // the case of normal reads)
      if (LOG.isDebugEnabled()) {
        LOG.debug("Closing scanner " + currentScannerCallable.scannerId);
      }
      Result[] r = currentScannerCallable.call(timeout);
      currentScannerCallable = null;
      return r;
    }
    // We need to do the following:
    // 1. When a scan goes out to a certain replica (default or not), we need to
    //   continue to hit that until there is a failure. So store the last successfully invoked
    //   replica
    // 2. We should close the "losing" scanners (scanners other than the ones we hear back
    //   from first)
    //
    RegionLocations rl =
        RpcRetryingCallerWithReadReplicas.getRegionLocations(
            true,
            RegionReplicaUtil.DEFAULT_REPLICA_ID,
            cConnection,
            tableName,
            currentScannerCallable.getRow());

    // allocate a boundedcompletion pool of some multiple of number of replicas.
    // We want to accomodate some RPCs for redundant replica scans (but are still in progress)
    BoundedCompletionService<Pair<Result[], ScannerCallable>> cs =
        new BoundedCompletionService<Pair<Result[], ScannerCallable>>(pool, rl.size() * 5);

    List<ExecutionException> exceptions = null;
    int submitted = 0, completed = 0;
    AtomicBoolean done = new AtomicBoolean(false);
    replicaSwitched.set(false);
    // submit call for the primary replica.
    submitted += addCallsForCurrentReplica(cs, rl);
    try {
      // wait for the timeout to see whether the primary responds back
      Future<Pair<Result[], ScannerCallable>> f =
          cs.poll(timeBeforeReplicas, TimeUnit.MICROSECONDS); // Yes, microseconds
      if (f != null) {
        Pair<Result[], ScannerCallable> r = f.get();
        if (r != null && r.getSecond() != null) {
          updateCurrentlyServingReplica(r.getSecond(), r.getFirst(), done, pool);
        }
        return r == null ? null : r.getFirst(); // great we got a response
      }
    } catch (ExecutionException e) {
      // the primary call failed with RetriesExhaustedException or DoNotRetryIOException
      // but the secondaries might still succeed. Continue on the replica RPCs.
      exceptions = new ArrayList<ExecutionException>(rl.size());
      exceptions.add(e);
      completed++;
    } catch (CancellationException e) {
      throw new InterruptedIOException(e.getMessage());
    } catch (InterruptedException e) {
      throw new InterruptedIOException(e.getMessage());
    }
    // submit call for the all of the secondaries at once
    // TODO: this may be an overkill for large region replication
    submitted += addCallsForOtherReplicas(cs, rl, 0, rl.size() - 1);
    try {
      while (completed < submitted) {
        try {
          Future<Pair<Result[], ScannerCallable>> f = cs.take();
          Pair<Result[], ScannerCallable> r = f.get();
          if (r != null && r.getSecond() != null) {
            updateCurrentlyServingReplica(r.getSecond(), r.getFirst(), done, pool);
          }
          return r == null ? null : r.getFirst(); // great we got an answer
        } catch (ExecutionException e) {
          // if not cancel or interrupt, wait until all RPC's are done
          // one of the tasks failed. Save the exception for later.
          if (exceptions == null) exceptions = new ArrayList<ExecutionException>(rl.size());
          exceptions.add(e);
          completed++;
        }
      }
    } catch (CancellationException e) {
      throw new InterruptedIOException(e.getMessage());
    } catch (InterruptedException e) {
      throw new InterruptedIOException(e.getMessage());
    } finally {
      // We get there because we were interrupted or because one or more of the
      // calls succeeded or failed. In all case, we stop all our tasks.
      cs.cancelAll(true);
    }

    if (exceptions != null && !exceptions.isEmpty()) {
      RpcRetryingCallerWithReadReplicas.throwEnrichedException(
          exceptions.get(0), retries); // just rethrow the first exception for now.
    }
    return null; // unreachable
  }
  /**
   * @param args
   * @throws Exception
   */
  public static void main(String[] args) {

    ExecutorService executor = Executors.newFixedThreadPool(10);
    // ThreadPoolExecutor executor = Executors.newFixedThreadPool(10);
    Callable<Long> worker =
        new Callable<Long>() {
          public Long call() throws Exception {
            long result = 0L;

            System.out.println("working...");
            while (true) {
              if (Thread.currentThread().isInterrupted()) {
                System.out.println("canceled...!");
                // Thread.currentThread().interrupt();
                break;
              }
              // Thread.sleep(1000); // simulates work
              result++;
              System.out.println("step " + result + "...");

              if (result == Long.MAX_VALUE) {
                break;
              }
            }

            return result;
          }
        };

    int startCount = Thread.activeCount();

    Future<Long> submit1 = executor.submit(worker);
    Future<Long> submit2 = executor.submit(worker);

    int middleCount = Thread.activeCount();

    try {
      Thread.sleep(500);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    submit1.cancel(true);
    submit2.cancel(true);

    System.out.println("Canceled! " + submit1.isCancelled());
    System.out.println("Done! " + submit1.isDone());
    try {
      System.out.println("Get! " + submit1.get());
    } catch (CancellationException e1) {
      // TODO Auto-generated catch block
      // e1.printStackTrace();
      System.out.println("ERROR: " + e1.getMessage());
    } catch (Exception e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }

    int lastCount = Thread.activeCount();

    System.out.println("Count: ");
    System.out.println(startCount);
    System.out.println(middleCount);
    System.out.println(lastCount);

    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    executor.shutdown();

    System.out.println("last count: " + Thread.activeCount());
  }