private void multiThreadedProjectTaskSegmentBuild(
      ConcurrencyDependencyGraph analyzer,
      ReactorContext reactorContext,
      MavenSession rootSession,
      CompletionService<ProjectSegment> service,
      TaskSegment taskSegment,
      Map<MavenProject, ProjectSegment> projectBuildList,
      ThreadOutputMuxer muxer) {

    // schedule independent projects
    for (MavenProject mavenProject : analyzer.getRootSchedulableBuilds()) {
      ProjectSegment projectSegment = projectBuildList.get(mavenProject);
      logger.debug("Scheduling: " + projectSegment.getProject());
      Callable<ProjectSegment> cb =
          createBuildCallable(rootSession, projectSegment, reactorContext, taskSegment, muxer);
      service.submit(cb);
    }

    // for each finished project
    for (int i = 0; i < analyzer.getNumberOfBuilds(); i++) {
      try {
        ProjectSegment projectBuild = service.take().get();
        if (reactorContext.getReactorBuildStatus().isHalted()) {
          break;
        }
        final List<MavenProject> newItemsThatCanBeBuilt =
            analyzer.markAsFinished(projectBuild.getProject());
        for (MavenProject mavenProject : newItemsThatCanBeBuilt) {
          ProjectSegment scheduledDependent = projectBuildList.get(mavenProject);
          logger.debug("Scheduling: " + scheduledDependent);
          Callable<ProjectSegment> cb =
              createBuildCallable(
                  rootSession, scheduledDependent, reactorContext, taskSegment, muxer);
          service.submit(cb);
        }
      } catch (InterruptedException e) {
        rootSession.getResult().addException(e);
        break;
      } catch (ExecutionException e) {
        // TODO MNG-5766 changes likely made this redundant
        rootSession.getResult().addException(e);
        break;
      }
    }

    // cancel outstanding builds (if any)  - this can happen if an exception is thrown in above
    // block

    Future<ProjectSegment> unprocessed;
    while ((unprocessed = service.poll()) != null) {
      try {
        unprocessed.get();
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      } catch (ExecutionException e) {
        throw new RuntimeException(e);
      }
    }
  }
  public InputStream createIncomingStream(StreamInitiation initiation) throws XMPPException {
    PacketCollector collector =
        connection.createPacketCollector(
            getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()));

    connection.sendPacket(super.createInitiationAccept(initiation, getNamespaces()));

    ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(2);
    CompletionService<InputStream> service =
        new ExecutorCompletionService<InputStream>(threadPoolExecutor);
    List<Future<InputStream>> futures = new ArrayList<Future<InputStream>>();
    InputStream stream = null;
    XMPPException exception = null;
    try {
      futures.add(service.submit(new NegotiatorService(collector)));
      futures.add(service.submit(new NegotiatorService(collector)));

      int i = 0;
      while (stream == null && i < futures.size()) {
        Future<InputStream> future;
        try {
          i++;
          future = service.poll(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
          continue;
        }

        if (future == null) {
          continue;
        }

        try {
          stream = future.get();
        } catch (InterruptedException e) {
          /* Do Nothing */
        } catch (ExecutionException e) {
          exception = new XMPPException(e.getCause());
        }
      }
    } finally {
      for (Future<InputStream> future : futures) {
        future.cancel(true);
      }
      collector.cancel();
      threadPoolExecutor.shutdownNow();
    }
    if (stream == null) {
      if (exception != null) {
        throw exception;
      } else {
        throw new XMPPException("File transfer negotiation failed.");
      }
    }

    return stream;
  }
 @Override
 public void run() {
   while (!end) {
     try {
       Future<String> result = completionservice.poll(20, TimeUnit.SECONDS);
       if (result != null) {
         String report = result.get();
         System.out.printf("ReportReceiver: Report Received:%s\n", report);
       }
     } catch (InterruptedException | ExecutionException e) {
       e.printStackTrace();
     }
   }
   System.out.printf("ReportSender: End\n");
 }
  /** 核心方法,如果任务没有完成就一直执行 */
  @Override
  public void run() {
    while (!end) {
      try {
        // 调用CompletionService接口的poll()方法,获取CompletionService执行的下个已完成任务的Future对象
        Future<String> result = service.poll(20, TimeUnit.SECONDS);
        if (result != null) {
          // 使用Future对象的get()方法获取任务的结果,并且将这些结果写入到控制台
          String report = result.get();
          System.out.printf("ReportReceiver: Report Received: %s\n", report);
        }
      } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
      }
    }

    System.out.printf("ReportSender: End\n");
  }
  @Override
  public void run() {
    while (!isEnd) {
      try {
        // 在结果的Future的列表中查看,如果是空的,则等待20秒。
        // 注意,是Future列表。CompletionService内部使用的是BlockingQueue<Future<V>>
        // 如果是无参数的poll,则如果是空,立刻返回。
        // take()方法则死守,直到非空为止
        // 注意:返回的结果在Future队列中。

        Future<String> fs = cs.poll(20, TimeUnit.SECONDS);
        if (fs != null) {
          System.out.println("Result is : " + fs.get());
        }
      } catch (InterruptedException | ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
    private void aggregateOnTheFly() throws InterruptedException, ExecutionException {
      boolean timedOut = false;
      boolean stoppedOnException = false;
      final StopWatch watch = new StopWatch();
      int aggregated = 0;
      boolean done = false;
      // not a for loop as on the fly may still run
      while (!done) {
        // check if we have already aggregate everything
        if (allTasksSubmitted.get() && aggregated >= total.get()) {
          LOG.debug("Done aggregating {} exchanges on the fly.", aggregated);
          break;
        }

        Future<Exchange> future;
        if (timedOut) {
          // we are timed out but try to grab if some tasks has been completed
          // poll will return null if no tasks is present
          future = completion.poll();
          LOG.trace(
              "Polled completion task #{} after timeout to grab already completed tasks: {}",
              aggregated,
              future);
        } else if (timeout > 0) {
          long left = timeout - watch.taken();
          if (left < 0) {
            left = 0;
          }
          LOG.trace("Polling completion task #{} using timeout {} millis.", aggregated, left);
          future = completion.poll(left, TimeUnit.MILLISECONDS);
        } else {
          LOG.trace("Polling completion task #{}", aggregated);
          // we must not block so poll every second
          future = completion.poll(1, TimeUnit.SECONDS);
          if (future == null) {
            // and continue loop which will recheck if we are done
            continue;
          }
        }

        if (future == null && timedOut) {
          // we are timed out and no more tasks complete so break out
          break;
        } else if (future == null) {
          // timeout occurred
          AggregationStrategy strategy = getAggregationStrategy(null);
          if (strategy instanceof TimeoutAwareAggregationStrategy) {
            // notify the strategy we timed out
            Exchange oldExchange = result.get();
            if (oldExchange == null) {
              // if they all timed out the result may not have been set yet, so use the original
              // exchange
              oldExchange = original;
            }
            ((TimeoutAwareAggregationStrategy) strategy)
                .timeout(oldExchange, aggregated, total.intValue(), timeout);
          } else {
            // log a WARN we timed out since it will not be aggregated and the Exchange will be lost
            LOG.warn(
                "Parallel processing timed out after {} millis for number {}. This task will be cancelled and will not be aggregated.",
                timeout,
                aggregated);
          }
          LOG.debug("Timeout occurred after {} millis for number {} task.", timeout, aggregated);
          timedOut = true;

          // mark that index as timed out, which allows us to try to retrieve
          // any already completed tasks in the next loop
          if (completion instanceof SubmitOrderedCompletionService) {
            ((SubmitOrderedCompletionService<?>) completion).timeoutTask();
          }
        } else {
          // there is a result to aggregate
          Exchange subExchange = future.get();

          // Decide whether to continue with the multicast or not; similar logic to the Pipeline
          Integer number = getExchangeIndex(subExchange);
          boolean continueProcessing =
              PipelineHelper.continueProcessing(
                  subExchange, "Parallel processing failed for number " + number, LOG);
          if (stopOnException && !continueProcessing) {
            // we want to stop on exception and an exception or failure occurred
            // this is similar to what the pipeline does, so we should do the same to not surprise
            // end users
            // so we should set the failed exchange as the result and break out
            result.set(subExchange);
            stoppedOnException = true;
            break;
          }

          // we got a result so aggregate it
          AggregationStrategy strategy = getAggregationStrategy(subExchange);
          doAggregate(strategy, result, subExchange);
        }

        aggregated++;
      }

      if (timedOut || stoppedOnException) {
        if (timedOut) {
          LOG.debug("Cancelling tasks due timeout after {} millis.", timeout);
        }
        if (stoppedOnException) {
          LOG.debug("Cancelling tasks due stopOnException.");
        }
        // cancel tasks as we timed out (its safe to cancel done tasks)
        running.set(false);
      }
    }
Beispiel #7
0
  /** @throws ExecutionException */
  protected void monitor() throws ExecutionException {
    int displayMillis = DISPLAY_MILLIS;
    int futureMillis = FUTURE_MILLIS;
    int sleepMillis = SLEEP_MILLIS;
    Future<TimedEvent[]> future = null;
    /* Initialize lastFutureMillis so that we do not get
     * warnings on slow queue startup.
     */
    long currentMillis = System.currentTimeMillis();
    long lastDisplayMillis = 0;
    long lastFutureMillis = currentMillis;
    TimedEvent[] lastEvent = null;

    logger.finest(
        "looping every "
            + sleepMillis
            + ", core="
            + pool.getCorePoolSize()
            + ", active="
            + pool.getActiveCount()
            + ", tasks="
            + taskCount);

    timer = new Timer();

    // run until all futures have been checked
    do {
      // try to avoid thread starvation
      yield();

      // check completed tasks
      // sometimes this goes so fast that we never leave the loop,
      // so progress is never displayed... so limit the number of loops.
      do {
        try {
          future = completionService.poll(SLEEP_MILLIS, TimeUnit.MILLISECONDS);
          if (null != future) {
            // record result, or throw exception
            lastFutureMillis = System.currentTimeMillis();
            try {
              lastEvent = future.get();
              if (null == lastEvent) {
                throw new FatalException("unexpected null event");
              }
              for (int i = 0; i < lastEvent.length; i++) {
                // discard events to reduce memory utilization
                if (null != lastEvent[i]) {
                  timer.add(lastEvent[i], false);
                }
              }
            } catch (ExecutionException e) {
              if (fatalErrors) {
                throw e;
              }
              Throwable cause = e.getCause();
              if (null != cause && cause instanceof FatalException) {
                throw (FatalException) cause;
              }
              logger.logException("non-fatal", e);
              timer.incrementEventCount(false);
            }
          }
        } catch (InterruptedException e) {
          // reset interrupt status and continue
          Thread.interrupted();
          logger.logException("interrupted in poll() or get()", e);
          continue;
        }

        currentMillis = System.currentTimeMillis();
        if (currentMillis - lastDisplayMillis > displayMillis) {
          lastDisplayMillis = currentMillis;
          logger.finer(
              "thread count: core="
                  + pool.getCorePoolSize()
                  + ", active="
                  + pool.getActiveCount()
                  + ", tasks="
                  + taskCount);
          if (null != lastEvent) {
            logger.info(
                ""
                    + timer.getEventCount()
                    + "/"
                    + taskCount
                    + ", "
                    + timer.getProgressMessage(false)
                    + ", "
                    + lastEvent[0].getDescription());

            if (config.doPrintCurrRate()) {
              String currMsg = timer.getCurrProgressMessage();
              if (currMsg != null) logger.info(currMsg);
            }
          }
        }

      } while (null != future);

      logger.finer(
          "running = "
              + running
              + ", terminated = "
              + pool.isTerminated()
              + ", last future = "
              + lastFutureMillis);
      // currentMillis has already been set recently
      if (currentMillis - lastFutureMillis > futureMillis) {
        logger.warning("no futures received in over " + futureMillis + " ms");
        break;
      }
    } while (running && !pool.isTerminated());
    // NB - caller will set running to false to ensure exit
  }