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; }
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); }