コード例 #1
0
        public async Task Activity_is_notified_when_a_command_is_delivered_immediately()
        {
            // arrange
            var order = CommandSchedulingTests.CreateOrder();

            var activity = new List <ICommandSchedulerActivity>();

            using (Configuration.Current
                   .Container
                   .Resolve <SqlCommandScheduler>()
                   .Activity
                   .Subscribe(a => activity.Add(a)))
            {
                // act
                order.Apply(new ShipOn(Clock.Now().Subtract(TimeSpan.FromDays(2))));
                await orderRepository.Save(order);

                await SchedulerWorkComplete();

                //assert
                activity.Should()
                .ContainSingle(a => a.ScheduledCommand.AggregateId == order.Id &&
                               a is CommandSucceeded);
            }
        }
コード例 #2
0
        public async Task A_command_is_not_marked_as_applied_if_no_handler_is_registered()
        {
            // arrange
            var order = CommandSchedulingTests.CreateOrder();

            order.Apply(
                new ChargeCreditCardOn
            {
                Amount     = 10,
                ChargeDate = Clock.Now().AddDays(10)
            });
            await orderRepository.Save(order);

            // act
            var schedulerWithNoHandlers = new SqlCommandScheduler(
                new Configuration().UseSqlEventStore());
            await schedulerWithNoHandlers.AdvanceClock(clockName, @by : TimeSpan.FromDays(20));

            // assert
            using (var db = new CommandSchedulerDbContext())
            {
                db.ScheduledCommands.Single(c => c.AggregateId == order.Id)
                .AppliedTime
                .Should()
                .BeNull();
            }
        }
コード例 #3
0
        public async Task When_a_command_has_been_completed_and_a_message_for_it_arrives_the_message_is_also_Completed()
        {
            var aggregateId = Any.Guid();

            // due in the past so that it's scheduled immediately
            var order = CommandSchedulingTests.CreateOrder(orderId: aggregateId)
                        .Apply(new ShipOn(Clock.Now().AddSeconds(-5)));

            queueSender.MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromSeconds(0);

            await orderRepository.Save(order);

            await RunCatchup();

            using (var receiver = CreateQueueReceiver())
            {
                var receivedMessages = new List <IScheduledCommand>();
                receiver.Messages
                .Where(c => c.AggregateId == aggregateId)
                .Subscribe(receivedMessages.Add);

                await receiver.StartReceivingMessages();

                await Task.Delay(TimeSpan.FromSeconds(5));

                receivedMessages.Should().ContainSingle(e => e.AggregateId == aggregateId);
            }

            using (var receiver = CreateQueueReceiver())
            {
                var receivedMessages = new List <IScheduledCommand>();

                receiver.Messages
                .Where(c => c.AggregateId == aggregateId)
                .Subscribe(receivedMessages.Add);

                await receiver.StartReceivingMessages();

                await Task.Delay(TimeSpan.FromSeconds(10));

                receivedMessages.Count().Should().Be(0);
            }
        }
コード例 #4
0
        public async Task When_a_command_trigger_message_arrives_early_it_is_not_Completed()
        {
            VirtualClock.Start(Clock.Now().AddHours(-1));

            var aggregateId     = Any.Guid();
            var appliedCommands = new List <ICommandSchedulerActivity>();

            scheduler.Activity
            .Where(c => c.ScheduledCommand.AggregateId == aggregateId)
            .Subscribe(appliedCommands.Add);

            using (var receiver = CreateQueueReceiver())
            {
                await receiver.StartReceivingMessages();

                // due enough in the future that the scheduler won't apply the commands immediately
                var order = await CommandSchedulingTests.CreateOrder(orderId : aggregateId)
                            .ApplyAsync(new ShipOn(Clock.Now().AddMinutes(2)));

                await orderRepository.Save(order);

                await RunCatchup();

                await receiver.Messages
                .FirstAsync(c => c.AggregateId == aggregateId)
                .Timeout(TimeSpan.FromMinutes(1));

                await Task.Delay(1000);

                appliedCommands.Should().BeEmpty();
            }

            Clock.Reset();

            using (var receiver = CreateQueueReceiver())
            {
                await receiver.StartReceivingMessages();

                await Task.Delay(1000);

                appliedCommands.Should().Contain(c => c.ScheduledCommand.AggregateId == aggregateId);
            }
        }
コード例 #5
0
        public async Task SqlCommandScheduler_Activity_is_notified_when_a_command_is_delivered_via_Trigger()
        {
            // arrange
            var order = CommandSchedulingTests.CreateOrder();

            var activity = new List <ICommandSchedulerActivity>();

            order.Apply(new ShipOn(Clock.Now().Add(TimeSpan.FromDays(2))));
            await orderRepository.Save(order);

            using (sqlCommandScheduler.Activity.Subscribe(activity.Add))
            {
                // act
                await clockTrigger.AdvanceClock(clockName, TimeSpan.FromDays(3));

                //assert
                activity.Should()
                .ContainSingle(a => a.ScheduledCommand.AggregateId == order.Id &&
                               a is CommandSucceeded);
            }
        }
コード例 #6
0
        public async Task When_ServiceBusCommandQueueSender_is_subscribed_to_the_service_bus_then_messages_are_scheduled_to_trigger_event_based_scheduled_commands()
        {
            VirtualClock.Start(DateTimeOffset.Now.AddHours(-13));

            using (var queueReceiver = CreateQueueReceiver())
            {
                var aggregateIds = Enumerable.Range(1, 5)
                                   .Select(_ => Guid.NewGuid())
                                   .ToArray();

                aggregateIds.ForEach(async id =>
                {
                    var order = CommandSchedulingTests.CreateOrder(orderId: id);

                    // due enough in the future that the scheduler won't apply the commands immediately
                    var due = Clock.Now().AddSeconds(5);
                    order.Apply(new ShipOn(due));

                    Console.WriteLine(new { ShipOrderId = order.Id, due });

                    await orderRepository.Save(order);
                });

                await RunCatchup();

                // reset the clock so that when the messages are delivered, the target commands are now due
                Clock.Reset();

                await queueReceiver.StartReceivingMessages();

                var activity = await scheduler.Activity
                               .Where(a => aggregateIds.Contains(a.ScheduledCommand.AggregateId))
                               .Take(5)
                               .ToList()
                               .Timeout(TimeSpan.FromMinutes(5));

                activity.Select(a => a.ScheduledCommand.AggregateId)
                .ShouldBeEquivalentTo(aggregateIds);
            }
        }