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

org.infinispan.commons.util.concurrent.CompositeNotifyingFuture Maven / Gradle / Ivy

There is a newer version: 9.1.7.Final
Show newest version
package org.infinispan.commons.util.concurrent;

import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * CompositeNotifyingFuture aggregates several NotifyingFuture and completes when all of them complete.
 *
 * @author gustavonalle
 * @since 7.1
 */
public final class CompositeNotifyingFuture extends NotifyingFutureImpl {

   private final CountDownLatch remaining;
   private final List> futures;
   private volatile boolean cancelled = false;

   public CompositeNotifyingFuture(List> futures) {
      this.futures = futures;
      this.remaining = new CountDownLatch(futures.size());
      InternalListener internalListener = new InternalListener();
      for (NotifyingFuture future : futures) {
         future.attachListener(internalListener);
      }
   }

   @Override
   public boolean isDone() {
      return remaining.getCount() == 0;
   }

   @Override
   public boolean isCancelled() {
      return cancelled;
   }

   @Override
   public boolean cancel(boolean mayInterruptIfRunning) {
      this.cancelled = true;
      boolean wasCancelled = true;
      for (NotifyingFuture future : futures) {
         wasCancelled &= future.cancel(mayInterruptIfRunning);
      }
      return wasCancelled;
   }

   @Override
   public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
      if (unit == null) throw new IllegalArgumentException("provided unit is null");
      if (cancelled) throw new CancellationException();
      if (!remaining.await(timeout, unit)) throw new TimeoutException();
      return super.get();
   }

   @Override
   public Void get() throws InterruptedException, ExecutionException {
      if (cancelled) throw new CancellationException();
      remaining.await();
      return super.get();
   }

   final class InternalListener implements FutureListener {
      @Override
      public void futureDone(Future future) {
         synchronized (this) {
            Throwable error = null;
            try {
               future.get();
            } catch (Throwable e) {
               error = e;
            }
            remaining.countDown();
            if (remaining.getCount() == 0) {
               if (error != null) {
                  notifyException(error);
               } else {
                  notifyDone(null);

               }
               setFuture(new NoOpFuture(null));
            }
         }

      }
   }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy