Esempio n. 1
0
        public void ShouldFindSingleChild()
        {
            var continuation = new Continuation {Id = _job.Id};

            var match = continuation.Find(_job);

            Assert.Equal(continuation, match);
        }
        public void ReturnsTrueForContinuableContinuationsWithoutAnyFailureHandlers()
        {
            var continuation = new Continuation {Status = JobStatus.Poisoned, ContinueAfterHandlingFailure = true};

            var result = continuation.CanContinue();

            Assert.True(result);
        }
        public void ReturnsFalseIfAnyChildContinuationIsNotContinuable()
        {
            var continuation = new Continuation
            {
                Status = JobStatus.Created,
                Children = new[] {new Continuation {Status = JobStatus.Poisoned}}
            };

            var result = continuation.CanContinue();

            Assert.False(result);
        }
Esempio n. 4
0
        public void ShouldFindNextContinuation()
        {
            var continuation = new Continuation
            {
                Id = Guid.NewGuid(),
                Next = new Continuation {Id = _job.Id}
            };

            var match = continuation.Find(_job);

            Assert.Equal(continuation.Next, match);
        }
Esempio n. 5
0
        public void ShouldFindContinuationsInOnAnyFailure()
        {
            var continuation = new Continuation
            {
                Id = Guid.NewGuid(),
                OnAnyFailed = new Continuation {Id = _job.Id}
            };

            var match = continuation.Find(_job);

            Assert.Equal(continuation.OnAnyFailed, match);
        }
        public void ReturnsFalseIfAnyFailureHandlerIsFailed()
        {
            var continuation = new Continuation
            {
                Status = JobStatus.Poisoned,
                ContinueAfterHandlingFailure = true,
                OnAllFailed = new Continuation {Status = JobStatus.Poisoned}
            };

            var result = continuation.CanContinue();

            Assert.False(result);
        }
        public void ReturnsNextIfAllContinuationsInGroupedIsComplete()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Parallel,
                Children = new[] {new Continuation {Status = JobStatus.Completed}},
                Next = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation.Next, pending.Single());
        }
        public void ReturnsFalseForGroupWithFailedChildrenAndFailedAnyFailureHandler()
        {
            var continuation = new Continuation
            {
                Status = JobStatus.Created,
                Children = new[] {new Continuation {Status = JobStatus.Poisoned}},
                ContinueAfterHandlingFailure = true,
                OnAnyFailed = new Continuation {Status = JobStatus.Poisoned},
                OnAllFailed = new Continuation {Status = JobStatus.Completed}
            };

            var result = continuation.CanContinue();

            Assert.False(result);
        }
Esempio n. 9
0
        public void ShouldFindContinuationsInGroup()
        {
            var matchingChild = new Continuation {Id = _job.Id};

            var continuation = new Continuation
            {
                Children = new []
                {
                    new Continuation { Id = Guid.NewGuid() },
                    matchingChild
                }
            };

            var match = continuation.Find(_job);

            Assert.Equal(matchingChild, match);
        }
        ConvertedActivity ConvertActivityGroupToContinuation(
            ActivityGroup activityGroup, 
            Job parent,
            IEnumerable<ExceptionFilter> inheritedExceptionFilters)
        {
            var jobs = Enumerable.Empty<Job>();

            /*
             *  Activities in a group inherit exception filters defined
             *  in the group as well as the ones inherited by the group.
             */
            var effectiveExceptionFilters = inheritedExceptionFilters.Concat(activityGroup.ExceptionFilters).ToArray();

            var convertedItems =
                activityGroup.Items.Select(item => ConvertCore(item, parent, effectiveExceptionFilters)).ToArray();

            jobs = convertedItems.Aggregate(jobs, (current, converted) => current.Concat(converted.Jobs));

            var continuation = new Continuation
            {
                Type = activityGroup.IsParallel ? ContinuationType.Parallel : ContinuationType.Sequence,
                ContinueAfterHandlingFailure = activityGroup.CanContinueAfterHandlingFailure,
                Children = convertedItems.Select(c => c.Continuation)
            };

            var onNext = ConvertCore(activityGroup.Next, parent, effectiveExceptionFilters);
            continuation.Next = onNext.Continuation;
            jobs = jobs.Concat(onNext.Jobs);

            var onAnyFailed = ConvertCore(activityGroup.OnAnyFailed, parent, effectiveExceptionFilters);
            continuation.OnAnyFailed = onAnyFailed.Continuation;
            jobs = jobs.Concat(onAnyFailed.Jobs);

            var onAllFailed = ConvertCore(activityGroup.OnAllFailed, parent, effectiveExceptionFilters);
            continuation.OnAllFailed = onAllFailed.Continuation;
            jobs = jobs.Concat(onAllFailed.Jobs);

            var onCancelled = ConvertCore(activityGroup.OnCancel, parent, effectiveExceptionFilters);
            if (onCancelled.Continuation != null)
                onCancelled.Continuation.CompensateForCancellation = true;
            continuation.OnCancelled = onCancelled.Continuation;
            jobs = jobs.Concat(onCancelled.Jobs);

            return new ConvertedActivity(continuation, jobs);
        }
        public void ReturnsNextIfAnyFailedContinuationHasCompletedRecoverableContinuation()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Parallel,
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Poisoned}
                },
                ContinueAfterHandlingFailure = true,
                OnAnyFailed = new Continuation {Status = JobStatus.Completed},
                Next = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation.Next, pending.Single());
        }
Esempio n. 12
0
        public static bool CanContinue(this Continuation item, bool isFailureHandler = false)
        {
            if (item.Children.Any()) // Is this a group?
            {
                var noOfSuccessfulChildren = item.Children.Count(c => c.CanContinue());

                if (noOfSuccessfulChildren == item.Children.Count())
                {
                    return(true);
                }

                // We come here if we've got at least one failing child.
                // First make sure we can continue if we run our failure handlers.
                if (!item.ContinueAfterHandlingFailure)
                {
                    return(false);
                }

                // Have they all failed?
                if (noOfSuccessfulChildren == 0)
                {
                    return((item.OnAllFailed == null || item.OnAllFailed.CanContinue(true)) &&
                           (item.OnAnyFailed == null || item.OnAnyFailed.CanContinue(true)));
                }

                return(item.OnAnyFailed == null || item.OnAnyFailed.CanContinue(true));
            }

            // If this item is already completed we can continue if there's no next item or
            // next item can also continue.
            if (item.Status == JobStatus.Completed)
            {
                return(!isFailureHandler || item.Next == null || item.Next.CanContinue());
            }

            if (item.Status == JobStatus.Poisoned)
            {
                // We cannot continue if await does not handle failures
                return(item.ContinueAfterHandlingFailure &&
                       (item.OnAllFailed == null || item.OnAllFailed.CanContinue(true)));
            }

            return(false);
        }
Esempio n. 13
0
        ConvertedActivity ConvertActivityGroupToContinuation(
            ActivityGroup activityGroup,
            Job parent,
            IEnumerable <ExceptionFilter> inheritedExceptionFilters)
        {
            var jobs = Enumerable.Empty <Job>();

            /*
             *  Activities in a group inherit exception filters defined
             *  in the group as well as the ones inherited by the group.
             */
            var effectiveExceptionFilters = inheritedExceptionFilters.Concat(activityGroup.ExceptionFilters).ToArray();

            var convertedItems =
                activityGroup.Items.Select(item => ConvertCore(item, parent, effectiveExceptionFilters)).ToArray();

            jobs = convertedItems.Aggregate(jobs, (current, converted) => current.Concat(converted.Jobs));

            var continuation = new Continuation
            {
                Type = activityGroup.IsParallel ? ContinuationType.Parallel : ContinuationType.Sequence,
                ContinueAfterHandlingFailure = activityGroup.CanContinueAfterHandlingFailure,
                Children = convertedItems.Select(c => c.Continuation)
            };

            var onNext = ConvertCore(activityGroup.Next, parent, effectiveExceptionFilters);

            continuation.Next = onNext.Continuation;
            jobs = jobs.Concat(onNext.Jobs);

            var onAnyFailed = ConvertCore(activityGroup.OnAnyFailed, parent, effectiveExceptionFilters);

            continuation.OnAnyFailed = onAnyFailed.Continuation;
            jobs = jobs.Concat(onAnyFailed.Jobs);

            var onAllFailed = ConvertCore(activityGroup.OnAllFailed, parent, effectiveExceptionFilters);

            continuation.OnAllFailed = onAllFailed.Continuation;
            jobs = jobs.Concat(onAllFailed.Jobs);

            return(new ConvertedActivity(continuation, jobs));
        }
        public void ReturnsAllIncompleteContinuationsInGrouped()
        {
            var created = new Continuation { Status = JobStatus.Created };
            var ready = new Continuation { Status = JobStatus.Ready };
            var completed = new Continuation {Status = JobStatus.Completed};
            var poisoned = new Continuation {Status = JobStatus.Poisoned};

            var continuation = new Continuation
            {
                Type = ContinuationType.Parallel,
                Children = new[] {created, completed, poisoned, ready}
            };

            var pending = continuation.PendingContinuations().ToArray();

            Assert.Contains(created, pending);
            Assert.Contains(ready, pending);
            Assert.DoesNotContain(completed, pending);
            Assert.DoesNotContain(poisoned, pending);
        }
Esempio n. 15
0
        public Job(
            Guid id,
            Type type,
            string method,
            object[] arguments,
            DateTime createdOn,
            Guid? rootId = null,
            Guid? parentId = null,
            Guid? correlationId = null,                        
            JobStatus status = JobStatus.Ready,
            int dispatchCount = 0,
            DateTime? retryOn = null,
            ExceptionFilter[] exceptionFilters = null,
            Continuation continuation = null,
            bool? suspended = null)
        {
            if(type == null) throw new ArgumentNullException("type");
            if (arguments == null) throw new ArgumentNullException("arguments");
            if (string.IsNullOrWhiteSpace(method)) throw new ArgumentException("A valid method is required.");

            Method = method;
            Id = id;
            Type = type;
            Arguments = arguments;
            CreatedOn = createdOn;

            RootId = rootId ?? id;
            ParentId = parentId;
            CorrelationId = correlationId ?? id;
            Status = status;
            DispatchCount = dispatchCount;
            RetryOn = retryOn;

            Properties = new Dictionary<string, object>();

            ExceptionFilters = exceptionFilters ?? new ExceptionFilter[0];
            Continuation = continuation;
            Suspended = suspended ?? false;
        }
Esempio n. 16
0
        ConvertedActivity ConvertSingleActivityToContinuation(
            SingleActivity singleActivity,
            Job parent,
            ExceptionFilter[] inheritedExceptionFilters)
        {
            var job = new Job(Guid.NewGuid(),
                              singleActivity.Type,
                              singleActivity.Name,
                              singleActivity.Arguments,
                              _now(),
                              rootId: parent.RootId,
                              parentId: parent.Id,
                              status: JobStatus.Created,
                              exceptionFilters: inheritedExceptionFilters.Concat(singleActivity.ExceptionFilters).ToArray());

            var jobs = new List <Job>(new[] { job });

            var continuation = new Continuation
            {
                Id   = job.Id,
                Type = ContinuationType.Single,
                ContinueAfterHandlingFailure = singleActivity.CanContinueAfterHandlingFailure
            };

            var onNext = ConvertCore(singleActivity.Next, parent, inheritedExceptionFilters);

            continuation.Next = onNext.Continuation;
            jobs.AddRange(onNext.Jobs);

            var onFailed = ConvertCore(singleActivity.OnFailed, parent, inheritedExceptionFilters);

            continuation.OnAllFailed = onFailed.Continuation;
            jobs.AddRange(onFailed.Jobs);

            return(new ConvertedActivity(continuation, jobs.AsEnumerable()));
        }
        public void ReturnsTrueIfAllContinuationsInGroupAreCompleted()
        {
            var continuation = new Continuation
            {
                Status = JobStatus.Created,
                Children = new[] {new Continuation {Status = JobStatus.Completed}}
            };

            var result = continuation.CanContinue();

            Assert.True(result);
        }
        public void ShouldReturnNextInSequence()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Sequence,
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Completed},
                    new Continuation {Status = JobStatus.Created},
                    new Continuation {Status = JobStatus.Created}
                }
            };

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation.Children.ElementAt(1), pending.Single());
        }
        public void ReturnsTrueIfAllFailureHandlersAreCompleted()
        {
            var continuation = new Continuation
            {
                Status = JobStatus.Poisoned,
                ContinueAfterHandlingFailure = true,
                OnAnyFailed = new Continuation {Status = JobStatus.Completed},
                OnAllFailed = new Continuation {Status = JobStatus.Completed}
            };

            var result = continuation.CanContinue();

            Assert.True(result);
        }
        public void ShouldReturnAnyFailedContinuationIfAnyContinuationInGroupIsFailed()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Parallel,
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Poisoned}
                },
                OnAnyFailed = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation.OnAnyFailed, pending.Single());
        }
        public void ShouldReturnAnyFailedHandlerWhenAnyItemFailsInSequence()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Sequence,
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Completed},
                    new Continuation {Status = JobStatus.Poisoned},
                    new Continuation {Status = JobStatus.Created}
                },
                OnAnyFailed = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation.OnAnyFailed, pending.Single());
        }
        public ConvertedActivity(Continuation continuation, IEnumerable<Job> jobs)
        {
            if (jobs == null) throw new ArgumentNullException("jobs");

            Continuation = continuation;
            Jobs = jobs;
        }
        public void ShouldReturnAnyFailedContinuationIfAllContinuationsInGroupIsFailed()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Parallel,
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Poisoned},
                    new Continuation {Status = JobStatus.Poisoned}
                },
                OnAnyFailed = new Continuation(),
                OnAllFailed = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.Contains(continuation.OnAnyFailed, pending);
        }
        public void ShouldNotReturnNextIfSingleContinuationIsCreated()
        {
            var continuation = new Continuation {Next = new Continuation()};

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation, pending.Single());
        }
        public void ShouldNotReturnNextIfSingleContinuationIsFailed()
        {
            var continuation = new Continuation {Status = JobStatus.Poisoned, Next = new Continuation()};

            var pending = continuation.PendingContinuations();

            Assert.Empty(pending);
        }
        public void ShouldNotReturnNextIfAllChilrenAreNotComplete()
        {
            var continuation = new Continuation
            {
                Children = new[]
                {
                    new Continuation()
                },
                Next = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.DoesNotContain(continuation.Next, pending);
        }
        public void ShouldNotReturnNextIfAnyContinuationInGroupIsFailed()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Parallel,
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Completed},
                    new Continuation {Status = JobStatus.Poisoned}
                },
                Next = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.Empty(pending);
        }
        public void ShouldNotReturnAllFailedContinuationIfAllContinuationsInGroupIsNotFailed()
        {
            var continuation = new Continuation
            {
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Completed},
                    new Continuation {Status = JobStatus.Poisoned}
                },
                OnAllFailed = new Continuation()
            };

            var pending = continuation.PendingContinuations();

            Assert.DoesNotContain(continuation.OnAllFailed, pending);
        }
        ConvertedActivity ConvertSingleActivityToContinuation(
            SingleActivity singleActivity,
            Job parent,
            ExceptionFilter[] inheritedExceptionFilters)
        {
            var job = new Job(Guid.NewGuid(),
                singleActivity.Type,
                singleActivity.Name,
                singleActivity.Arguments,
                _now(),
                rootId: parent.RootId,
                parentId: parent.Id,
                status: JobStatus.Created,
                exceptionFilters: inheritedExceptionFilters.Concat(singleActivity.ExceptionFilters).ToArray());

            var jobs = new List<Job>(new[] {job});

            var continuation = new Continuation
            {
                Id = job.Id,
                Type = ContinuationType.Single,
                ContinueAfterHandlingFailure = singleActivity.CanContinueAfterHandlingFailure
            };

            var onNext = ConvertCore(singleActivity.Next, parent, inheritedExceptionFilters);
            continuation.Next = onNext.Continuation;
            jobs.AddRange(onNext.Jobs);

            var onFailed = ConvertCore(singleActivity.OnFailed, parent, inheritedExceptionFilters);
            continuation.OnAllFailed = onFailed.Continuation;
            jobs.AddRange(onFailed.Jobs);

            var onCancel = ConvertCore(singleActivity.OnCancel, parent, inheritedExceptionFilters);
            if (onCancel.Continuation != null)
                onCancel.Continuation.CompensateForCancellation = true;
            continuation.OnCancelled = onCancel.Continuation;
            jobs.AddRange(onCancel.Jobs);

            return new ConvertedActivity(continuation, jobs.AsEnumerable());
        }
        public void ReturnsSingleIncompleteContinuation(JobStatus incompleteStatus)
        {
            var continuation = new Continuation {Status = incompleteStatus};

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation, pending.Single());
        }
Esempio n. 31
0
        public static IEnumerable <Continuation> PendingContinuations(this Continuation item)
        {
            if (item == null)
            {
                return(Enumerable.Empty <Continuation>());
            }

            if (item.Type == ContinuationType.Single)
            {
                if (item.Status == JobStatus.Created || item.Status == JobStatus.Ready)
                {
                    return new[] { item }
                }
                ;

                if (item.Status == JobStatus.Poisoned)
                {
                    var failedHandler = item.OnAllFailed.PendingContinuations().ToArray();

                    if (!failedHandler.Any() && item.CanContinue())
                    {
                        return(item.Next.PendingContinuations());
                    }

                    return(failedHandler);
                }

                if (item.Status == JobStatus.Completed)
                {
                    return(item.Next.PendingContinuations());
                }
            }

            if (item.Type == ContinuationType.Parallel)
            {
                var children = item.Children.SelectMany(a => a.PendingContinuations()).ToArray();
                if (children.Any())
                {
                    return(children);
                }
            }

            if (item.Type == ContinuationType.Sequence)
            {
                foreach (var child in item.Children)
                {
                    var children = child.PendingContinuations().ToArray();
                    if (children.Any())
                    {
                        return(children);
                    }
                    if (!child.CanContinue())
                    {
                        break;
                    }
                }
            }

            var anyFailureHandlers = Enumerable.Empty <Continuation>();
            var allFailureHandlers = Enumerable.Empty <Continuation>();

            var failedChildren = item.Children.Where(c => !c.CanContinue()).ToArray();

            if (failedChildren.Any())
            {
                anyFailureHandlers = item.OnAnyFailed.PendingContinuations();
            }
            if (failedChildren.Length == item.Children.Count())
            {
                allFailureHandlers = item.OnAllFailed.PendingContinuations();
            }

            var resultArray = anyFailureHandlers.Concat(allFailureHandlers).ToArray();

            return(resultArray.Any()
                ? resultArray
                : item.CanContinue() ? item.Next.PendingContinuations() : Enumerable.Empty <Continuation>());
        }
        public void ShouldNotReturnNextInSequenceIfCurrentIsFailed()
        {
            var continuation = new Continuation
            {
                Type = ContinuationType.Sequence,
                Children = new[]
                {
                    new Continuation {Status = JobStatus.Completed},
                    new Continuation {Status = JobStatus.Poisoned},
                    new Continuation {Status = JobStatus.Created}
                }
            };

            var pending = continuation.PendingContinuations();

            Assert.Empty(pending);
        }
        public void ReturnsOnFailedContinuationIfSingleContinuationIsFailed()
        {
            var continuation = new Continuation {Status = JobStatus.Poisoned, OnAllFailed = new Continuation()};

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation.OnAllFailed, pending.Single());
        }
        public void ReturnsNextIfSingleContinuationIsCompleted()
        {
            var continuation = new Continuation {Status = JobStatus.Completed, Next = new Continuation()};

            var pending = continuation.PendingContinuations();

            Assert.Equal(continuation.Next, pending.Single());
        }