Esempio n. 1
0
        public static Future <T> FromIterator <T>(Func <FuturePublisher <T>, IEnumerable <Future> > iteratorPattern, bool stopOnFutureErrors)
        {
            var publisher = new FuturePublisher <T>();
            var result    = publisher.Future;

            var iteratorFuture = iteratorPattern(publisher)
                                 .ExecuteSequentially(stopOnFutureErrors);

            iteratorFuture.OnComplete(() =>
            {
                if (result.IsComplete)
                {
                    return;
                }

                var error = iteratorFuture.HasError
                                        ? iteratorFuture.Error
                                        : new InvalidOperationException("The iterator pattern completed without publishing a result.");

                result.SetError(error);
            });

            return(result);
        }
Esempio n. 2
0
        /// <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);
        }