예제 #1
0
        private static async Task FailScheduledCommand <TAggregate>(
            IEventSourcedRepository <TAggregate> repository,
            IScheduledCommand <TAggregate> scheduled,
            Exception exception  = null,
            TAggregate aggregate = null)
            where TAggregate : class, IEventSourced
        {
            var failure = (CommandFailed)createMethod
                          .MakeGenericMethod(scheduled.Command.GetType())
                          .Invoke(null, new object[] { scheduled.Command, scheduled, exception });

            var previousAttempts = scheduled.IfHas <int>(s => s.Metadata.NumberOfPreviousAttempts)
                                   .ElseDefault();

            failure.NumberOfPreviousAttempts = previousAttempts;

            if (aggregate != null)
            {
                // TODO: (FailScheduledCommand) refactor so that getting hold of the handler is simpler
                var scheduledCommandOfT = scheduled.Command as Command <TAggregate>;
                if (scheduledCommandOfT != null)
                {
                    if (scheduledCommandOfT.Handler != null)
                    {
                        await scheduledCommandOfT.Handler
                        .HandleScheduledCommandException((dynamic)aggregate,
                                                         (dynamic)failure);
                    }
                }

                if (!(exception is ConcurrencyException))
                {
                    try
                    {
                        await repository.Save(aggregate);
                    }
                    catch (Exception ex)
                    {
                        // TODO: (FailScheduledCommand) surface this more clearly
                        Trace.Write(ex);
                    }
                }
                else if (scheduled.Command is ConstructorCommand <TAggregate> )
                {
                    failure.Cancel();
                    scheduled.Result = failure;
                    return;
                }
            }

            if (!failure.IsCanceled &&
                failure.RetryAfter == null &&
                failure.NumberOfPreviousAttempts < DefaultNumberOfRetriesOnException)
            {
                failure.Retry(TimeSpan.FromMinutes(Math.Pow(failure.NumberOfPreviousAttempts + 1, 2)));
            }

            scheduled.Result = failure;
        }
예제 #2
0
        private static ScheduledCommandResult FailScheduledCommand <TAggregate>(
            IEventSourcedRepository <TAggregate> repository,
            IScheduledCommand <TAggregate> scheduled,
            Exception exception  = null,
            TAggregate aggregate = null)
            where TAggregate : class, IEventSourced
        {
            var failure = (CommandFailed)createMethod
                          .MakeGenericMethod(scheduled.Command.GetType())
                          .Invoke(null, new object[] { scheduled.Command, scheduled, exception });

            var previousAttempts = scheduled.IfHas <int>(s => s.Metadata.NumberOfPreviousAttempts)
                                   .ElseDefault();

            failure.NumberOfPreviousAttempts = previousAttempts;

            if (aggregate != null)
            {
                // TODO: (FailScheduledCommand) refactor so that getting hold of the handler is simpler
                scheduled.Command
                .IfTypeIs <Command <TAggregate> >()
                .ThenDo(c =>
                {
                    if (c.Handler != null)
                    {
                        Task task = c.Handler
                                    .HandleScheduledCommandException((dynamic)aggregate,
                                                                     (dynamic)failure);
                        task.Wait();
                    }
                });

                if (!(exception is ConcurrencyException))
                {
                    try
                    {
                        repository.Save(aggregate);
                    }
                    catch (Exception ex)
                    {
                        // TODO: (FailScheduledCommand) surface this more clearly
                        Trace.Write(ex);
                    }
                }
            }
            else
            {
                if (failure.NumberOfPreviousAttempts < 5)
                {
                    failure.Retry(TimeSpan.FromMinutes(failure.NumberOfPreviousAttempts + 1));
                }
            }

            return(failure);
        }