All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.infinispan.executors.ExecutorAllCompletionService Maven / Gradle / Ivy

There is a newer version: 9.1.7.Final
Show newest version
package org.infinispan.executors;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Exectues given tasks in provided executor.
 *
 * @author Radim Vansa <[email protected]>
 */
public class ExecutorAllCompletionService implements CompletionService {
   private ExecutorCompletionService executorService;
   private AtomicReference firstException = new AtomicReference();
   private AtomicLong scheduled = new AtomicLong();
   private AtomicLong completed = new AtomicLong();

   public ExecutorAllCompletionService(Executor executor) {
      this.executorService = new ExecutorCompletionService(executor);
   }

   @Override
   public Future submit(final Callable task) {
      scheduled.incrementAndGet();
      Future future = executorService.submit(task);
      pollUntilEmpty();
      return future;
   }

   @Override
   public Future submit(final Runnable task, Void result) {
      scheduled.incrementAndGet();
      Future future = executorService.submit(task, result);
      pollUntilEmpty();
      return future;
   }

   private void pollUntilEmpty() {
      Future completedFuture;
      while ((completedFuture = executorService.poll()) != null) {
         try {
            completedFuture.get();
         } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
         } catch (ExecutionException e) {
            if (firstException.get() == null) {
               firstException.compareAndSet(null, e);
            }
         } finally {
            completed.incrementAndGet();
         }
      }
   }

   /**
    * @return True if all currently scheduled tasks have already been completed, false otherwise;
    */
   public boolean isAllCompleted() {
      pollUntilEmpty();
      return completed.get() >= scheduled.get();
   }

   public long getScheduledTasks() {
      return scheduled.get();
   }

   public long getCompletedTasks() {
      return completed.get();
   }

   public void waitUntilAllCompleted() {
      while (completed.get() < scheduled.get()) {
         // Here is a race - if we poll the last scheduled entry elsewhere, we may wait
         // another 100 ms until we realize that everything has already completed.
         // Nevertheless, that's not so bad.
         try {
            Future future = poll(100, TimeUnit.MILLISECONDS);
            if (future != null) {
               future.get();
            }
         } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
         } catch (ExecutionException e) {
            if (firstException.get() == null) {
               firstException.compareAndSet(null, e);
            }
         }
      }
   }

   public boolean isExceptionThrown() {
      return firstException.get() != null;
   }

   public ExecutionException getFirstException() {
      return firstException.get();
   }

   @Override
   public Future take() throws InterruptedException {
      Future future = executorService.take();
      completed.incrementAndGet();
      return future;
   }

   @Override
   public Future poll() {
      Future future = executorService.poll();
      if (future != null) {
         completed.incrementAndGet();
      }
      return future;
   }

   @Override
   public Future poll(long timeout, TimeUnit unit) throws InterruptedException {
      Future future = executorService.poll(timeout, unit);
      if (future != null) {
         completed.incrementAndGet();
      }
      return future;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy