public override async Task When_a_scheduled_command_depends_on_an_event_that_never_arrives_it_is_eventually_abandoned() { var orderId = Any.Guid(); await Save(new Order(new CreateOrder(Any.FullName()) { AggregateId = orderId })); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = Any.Guid(), ETag = Any.Guid().ToString() }; await Schedule(orderId, new AddItem { ProductName = Any.Paragraph(3), Price = 10m }, deliveryDependsOn : prerequisiteEvent); for (var i = 0; i < 7; i++) { await AdvanceClock(by : 90.Days()); } using (var db = CommandSchedulerDbContext()) { var command = db.ScheduledCommands.Single(c => c.AggregateId == orderId); command.AppliedTime .Should() .NotHaveValue(); command.Attempts .Should() .BeGreaterOrEqualTo(5); command.FinalAttemptTime .Should() .HaveValue(); } }
public async Task When_an_immediately_scheduled_command_depends_on_an_event_then_delivery_in_memory_waits_on_the_event_being_saved() { var orderId = Any.Guid(); var customerName = Any.FullName(); var prerequisiteAggregateId = Any.Guid(); var prerequisiteETag = Any.Guid().ToString(); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = prerequisiteAggregateId, ETag = prerequisiteETag }; await Schedule(orderId, new CreateOrder(customerName) { AggregateId = orderId }, deliveryDependsOn : prerequisiteEvent); // sanity check that the order is null var order = await Get <Order>(orderId); order.Should().BeNull(); await Save(new CustomerAccount(prerequisiteAggregateId) .Apply(new ChangeEmailAddress(Any.Email()) { ETag = prerequisiteETag })); await SchedulerWorkComplete(); // assert // now the order should have been created order = await Get <Order>(orderId); order.Should().NotBeNull(); }
public override async Task When_an_immediately_scheduled_command_depends_on_a_precondition_that_has_not_been_met_yet_then_there_is_not_initially_an_attempt_recorded() { var orderId = Any.Guid(); var customerName = Any.FullName(); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = Any.Guid(), ETag = Any.Guid().ToString() }; var scheduledCommand = await Configuration .Current .CommandScheduler <Order>() .Schedule(orderId, new CreateOrder(customerName) { AggregateId = orderId }, deliveryDependsOn: prerequisiteEvent); var order = await Get <Order>(orderId); order.Should().BeNull(); scheduledCommand.Result.Should().BeOfType <CommandScheduled>(); using (var db = CommandSchedulerDbContext()) { var command = db.ScheduledCommands.Single(c => c.AggregateId == orderId); command.AppliedTime .Should() .NotHaveValue(); command.Attempts .Should() .Be(0); } }
public async Task When_a_scheduled_command_depends_on_an_event_that_never_arrives_it_is_eventually_abandoned() { VirtualClock.Start(); var container = Configuration.Current.Container; var commandScheduler = container.Resolve<ICommandScheduler<Order>>(); var orderId = Any.Guid(); await orderRepository.Save(new Order(new CreateOrder(Any.FullName()) { AggregateId = orderId })); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = Any.Guid(), ETag = Any.Guid().ToString() }; await commandScheduler.Schedule(orderId, new AddItem { ProductName = Any.Paragraph(3), Price = 10m }, deliveryDependsOn: prerequisiteEvent); for (var i = 0; i < 7; i++) { VirtualClock.Current.AdvanceBy(TimeSpan.FromMinutes(90)); Console.WriteLine( (await clockTrigger.Trigger(commands => commands.Due().Where(c => c.AggregateId == orderId))).ToLogString()); } using (var db = new CommandSchedulerDbContext()) { var command = db.ScheduledCommands.Single(c => c.AggregateId == orderId); command.AppliedTime .Should() .BeNull(); command.Attempts .Should() .BeGreaterOrEqualTo(5); command.FinalAttemptTime .Should() .NotBeNull(); } }
public async Task When_an_immediately_scheduled_command_depends_on_an_event_then_delivery_in_memory_waits_on_the_event_being_saved() { var container = Configuration.Current.Container; var commandScheduler = container.Resolve<ICommandScheduler<Order>>(); var orderId = Any.Guid(); var customerName = Any.FullName(); var prerequisiteAggregateId = Any.Guid(); var prerequisiteETag = Any.Guid().ToString(); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = prerequisiteAggregateId, ETag = prerequisiteETag }; await commandScheduler.Schedule(orderId, new CreateOrder(customerName) { AggregateId = orderId }, deliveryDependsOn: prerequisiteEvent); // sanity check that the order is null var order = await orderRepository.GetLatest(orderId); order.Should().BeNull(); await accountRepository.Save(new CustomerAccount(prerequisiteAggregateId) .Apply(new ChangeEmailAddress(Any.Email()) { ETag = prerequisiteETag })); await SchedulerWorkComplete(); // assert // now the order should have been created order = await orderRepository.GetLatest(orderId); order.Should().NotBeNull(); }
public async Task When_an_immediately_scheduled_command_depends_on_an_event_that_has_not_been_saved_yet_then_there_is_not_initially_a_concurrency_exception() { var container = Configuration.Current.Container; var commandScheduler = container.Resolve<ICommandScheduler<Order>>(); var orderId = Any.Guid(); var customerName = Any.FullName(); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = Any.Guid(), ETag = Any.Guid().ToString() }; var scheduledCommand = await commandScheduler.Schedule(orderId, new CreateOrder(customerName) { AggregateId = orderId }, deliveryDependsOn: prerequisiteEvent); var order = await orderRepository.GetLatest(orderId); order.Should().BeNull(); scheduledCommand.Result.Should().BeOfType<CommandScheduled>(); using (var db = new CommandSchedulerDbContext()) { var command = db.ScheduledCommands.Single(c => c.AggregateId == orderId); command.AppliedTime .Should() .BeNull(); command.Attempts .Should() .Be(0); } }
public override async Task When_a_scheduled_command_depends_on_an_event_that_never_arrives_it_is_eventually_abandoned() { var orderId = Any.Guid(); await Save(new Order(new CreateOrder(Any.FullName()) { AggregateId = orderId })); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = Any.Guid(), ETag = Any.Guid().ToString() }; await Schedule(orderId, new AddItem { ProductName = Any.Paragraph(3), Price = 10m }, deliveryDependsOn: prerequisiteEvent); for (var i = 0; i < 7; i++) { await AdvanceClock(by: 90.Days()); } using (var db = CommandSchedulerDbContext()) { var command = db.ScheduledCommands.Single(c => c.AggregateId == orderId); command.AppliedTime .Should() .NotHaveValue(); command.Attempts .Should() .BeGreaterOrEqualTo(5); command.FinalAttemptTime .Should() .HaveValue(); } }
public override async Task When_an_immediately_scheduled_command_depends_on_a_precondition_that_has_not_been_met_yet_then_there_is_not_initially_an_attempt_recorded() { var orderId = Any.Guid(); var customerName = Any.FullName(); var prerequisiteEvent = new CustomerAccount.Created { AggregateId = Any.Guid(), ETag = Any.Guid().ToString() }; var scheduledCommand = await Configuration .Current .CommandScheduler<Order>() .Schedule(orderId, new CreateOrder(customerName) { AggregateId = orderId }, deliveryDependsOn: prerequisiteEvent); var order = await Get<Order>(orderId); order.Should().BeNull(); scheduledCommand.Result.Should().BeOfType<CommandScheduled>(); using (var db = CommandSchedulerDbContext()) { var command = db.ScheduledCommands.Single(c => c.AggregateId == orderId); command.AppliedTime .Should() .NotHaveValue(); command.Attempts .Should() .Be(0); } }