internal static ScheduledCommandInterceptor <TAggregate> WithInMemoryDeferredScheduling <TAggregate>(Configuration configuration) where TAggregate : class { return(async(command, next) => { var etagStore = configuration.Container.Resolve <InMemoryCommandETagStore>(); if (!etagStore.TryAdd(scope: command.TargetId, etag: command.Command.ETag)) { command.Result = new CommandDeduplicated(command, "Schedule"); } else if (command.Result == null) { var clock = Clock.Current; command.Result = new CommandScheduled(command, clock); VirtualClock.Schedule( command, command.DueTime ?? Clock.Now().AddTicks(1), (s, c) => { Domain.CommandScheduler.DeliverImmediatelyOnConfiguredScheduler(c, configuration).Wait(); return Disposable.Empty; }); } await next(command); }); }
/// <summary> /// Schedules the specified command. /// </summary> /// <param name="scheduledCommand">The scheduled command.</param> /// <returns>A task that is complete when the command has been successfully scheduled.</returns> public async Task Schedule(IScheduledCommand <TAggregate> scheduledCommand) { var dueTime = scheduledCommand.DueTime; var domainNow = Clock.Current.Now(); if (dueTime == null || dueTime <= domainNow) { Debug.WriteLine(string.Format("Schedule (applying {1} immediately): @ {0}", domainNow, scheduledCommand.Command.CommandName)); // schedule immediately await Deliver(scheduledCommand); return; } // schedule for later VirtualClock.Schedule(scheduledCommand, dueTime.Value, (s, command) => { try { Deliver(command).Wait(); } catch (Exception exception) { Console.WriteLine("InMemoryCommandScheduler caught:\n" + exception); } return(Disposable.Empty); }); }
/// <summary> /// Schedules the specified command. /// </summary> /// <param name="scheduledCommand">The scheduled command.</param> /// <returns>A task that is complete when the command has been successfully scheduled.</returns> public async Task Schedule(IScheduledCommand <TAggregate> scheduledCommand) { var dueTime = scheduledCommand.DueTime; var domainNow = Clock.Current.Now(); if (dueTime == null || dueTime <= domainNow) { if (!await VerifyPrecondition(scheduledCommand)) { this.DeliverIfPreconditionIsSatisfiedWithin( TimeSpan.FromSeconds(3), scheduledCommand, Configuration.Current.EventBus); } else { Debug.WriteLine(string.Format("Schedule (applying {1} immediately): @ {0}", domainNow, scheduledCommand.Command.CommandName)); resetEvent.Reset(); // schedule immediately await Deliver(scheduledCommand); } return; } // schedule for later VirtualClock.Schedule(scheduledCommand, dueTime.Value, (s, command) => { resetEvent.Reset(); try { Deliver(command).Wait(); } catch (Exception exception) { Console.WriteLine("InMemoryCommandScheduler caught:\n" + exception); } return(Disposable.Empty); }); }
internal static ScheduledCommandInterceptor <TAggregate> WithInMemoryDeferredScheduling <TAggregate>(Configuration configuration) where TAggregate : class, IEventSourced { return(async(command, next) => { if (command.Result == null) { command.Result = new CommandScheduled(command); // deliver the command immediately if appropriate if (command.IsDue()) { var preconditionVerifier = configuration.Container.Resolve <ICommandPreconditionVerifier>(); // sometimes the command depends on a precondition event that hasn't been saved if (!await preconditionVerifier.IsPreconditionSatisfied(command)) { Domain.CommandScheduler.DeliverIfPreconditionIsSatisfiedSoon(command, configuration); } else { await Domain.CommandScheduler.DeliverImmediatelyOnConfiguredScheduler(command, configuration); return; } } if (!(command.Result is CommandDelivered)) { VirtualClock.Schedule( command, command.DueTime ?? Clock.Now().AddTicks(1), (s, c) => { Domain.CommandScheduler.DeliverImmediatelyOnConfiguredScheduler(c, configuration).Wait(); return Disposable.Empty; }); } } await next(command); }); }