// todo - when we switch to 4.0 use covariant instead of generic /// <summary> /// Waits for all futures to complete. /// </summary> /// <param name="futures">The futures to wait for.</param> public static void WaitAll <T>(this IEnumerable <T> futures) where T : Future { var latch = new CountDownLatch(futures.Count(), false); foreach (var future in futures) { future.OnComplete(latch.Decrement); } latch.Wait(); }
/// <summary> /// Combines the specified futures into one. If all succeed the result future will succeed. Otherwise the future will fail. /// </summary> /// <param name="futures">The futures.</param> /// <returns>A combined future.</returns> public static Future Combine(this IEnumerable <IFuture> futures) { var publisher = new FuturePublisher <int>(); bool failed = false; List <IFuture> incompleteFutures = null; foreach (var future in futures) { if (future.Status == FutureStatus.Failure) { _log.Error(future.Error); failed = true; } else { if (incompleteFutures == null) { incompleteFutures = new List <IFuture>(); } incompleteFutures.Add(future); } } if (incompleteFutures == null) { if (failed) { publisher.SetError(new ApplicationException("One or more futures failed. See log for details.")); } else { publisher.SetResult(0); } return(publisher.Future); } var latch = new CountDownLatch(incompleteFutures.Count, false); latch.Signaled += (sender, args) => { if (failed) { publisher.SetError(new ApplicationException("One or more futures failed. See log for details.")); } else { publisher.SetResult(0); } }; foreach (var future in incompleteFutures) { var temp = future; future.OnComplete(() => { if (temp.Status == FutureStatus.Failure) { failed = true; _log.Error(temp.Error); } latch.Decrement(); }); } return(publisher.Future); }