Example #1
0
 private static void RunAfter(IEnumerable <IStep> steps, CancellationBoundary boundary)
 {
     foreach (var step in steps.Where(s => s.Boundary >= boundary))
     {
         step.Trigger();
     }
 }
Example #2
0
        private void Configure(CancellationBoundary testBoundary)
        {
            _commandHandler = new ManualCommandHandler();
            _subscriber     = new ManualSubscriber();

            var resolver = EventFlowOptions.New()
                           .AddCommands(typeof(ThingyPingCommand))
                           .AddEvents(typeof(ThingyPingEvent))
                           .UseInMemoryReadStoreFor <InMemoryThingyReadModel>()
                           .Configure(c => c.CancellationBoundary = testBoundary)
                           .RegisterServices(s =>
            {
                s.Decorate <IInMemoryReadStore <InMemoryThingyReadModel>, ManualReadStore>();
                s.Decorate <IEventPersistence, ManualEventPersistence>();

                s.AddTransient <ICommandHandler <ThingyAggregate, ThingyId, IExecutionResult, ThingyPingCommand> >(c => _commandHandler);
                s.AddTransient <ISubscribeSynchronousTo <ThingyAggregate, ThingyId, ThingyPingEvent> >(c => _subscriber);
                s.AddTransient <IScopedContext, ScopedContext>();
            })
                           .ServiceCollection.BuildServiceProvider();

            _eventPersistence = (ManualEventPersistence)resolver.GetRequiredService <IEventPersistence>();
            _readStore        = (ManualReadStore)resolver.GetRequiredService <IInMemoryReadStore <InMemoryThingyReadModel> >();
            _commandBus       = resolver.GetRequiredService <ICommandBus>();
        }
Example #3
0
        private void Configure(CancellationBoundary testBoundary)
        {
            _commandHandler   = new ManualCommandHandler();
            _subscriber       = new ManualSubscriber();
            _eventPersistence = null;
            _readStore        = null;

            var resolver = EventFlowOptions
                           .New
                           .AddCommands(typeof(ThingyPingCommand))
                           .AddEvents(typeof(ThingyPingEvent))
                           .UseInMemoryReadStoreFor <InMemoryThingyReadModel>()
                           .Configure(c => c.CancellationBoundary = testBoundary)
                           .RegisterServices(s =>
            {
                s.Decorate <IInMemoryReadStore <InMemoryThingyReadModel> >((c, i) =>
                                                                           _readStore ?? (_readStore = new ManualReadStore(i)));
                s.Decorate <IEventPersistence>((c, i) =>
                                               _eventPersistence ?? (_eventPersistence = new ManualEventPersistence(i)));
                s.Register <ICommandHandler <ThingyAggregate, ThingyId, IExecutionResult, ThingyPingCommand> >(c =>
                                                                                                               _commandHandler);
                s.Register <ISubscribeSynchronousTo <ThingyAggregate, ThingyId, ThingyPingEvent> >(c => _subscriber);
                s.Register <IScopedContext, ScopedContext>(Lifetime.Scoped);
            })
                           .CreateResolver();

            _commandBus = resolver.Resolve <ICommandBus>();
        }
 public Setup()
 {
     RetryCountOnOptimisticConcurrencyExceptions       = 4;
     WaitThenTryAfterOnOptimisticConcurrencyExceptions = TimeSpan.FromMilliseconds(1000);
     ThrowSubscriberExceptions        = false;
     IsAsynchronousSubscribersEnabled = false;
     CancellationBoundary             = CancellationBoundary.BeforeCommittingEvents;
 }
Example #5
0
 internal EventFlowConfiguration()
 {
     PopulateReadModelEventPageSize = 200;
     NumberOfRetriesOnOptimisticConcurrencyExceptions  = 4;
     DelayBeforeRetryOnOptimisticConcurrencyExceptions = TimeSpan.FromMilliseconds(100);
     ThrowSubscriberExceptions        = false;
     IsAsynchronousSubscribersEnabled = false;
     CancellationBoundary             = CancellationBoundary.BeforeCommittingEvents;
 }
Example #6
0
        public async Task ShouldCancelBeforeBarrierOrRunToEnd(
            CancellationBoundary configuredBoundary,
            CancellationBoundary cancelAt)
        {
            // Arrange

            Configure(configuredBoundary);

            var safetyTimeout = Debugger.IsAttached
                ? TimeSpan.FromDays(1)
                : TimeSpan.FromSeconds(1);

            var id          = ThingyId.New;
            var pingId      = PingId.New;
            var tokenSource = new CancellationTokenSource(safetyTimeout);
            var token       = tokenSource.Token;

            var steps = CreateSteps(id);

            // Act

            var publishTask = _commandBus.PublishAsync(new ThingyPingCommand(id, pingId), token);

            RunUpTo(steps, cancelAt);
            tokenSource.Cancel();
            RunAfter(steps, cancelAt);

            var publishTaskOrSafetyTimeout = await Task.WhenAny(
                publishTask,
                Task.Delay(safetyTimeout, CancellationToken.None));

            if (publishTaskOrSafetyTimeout == publishTask)
            {
                try
                {
                    // Command could have failed or been cancelled.
                    await publishTask;
                }
                catch (OperationCanceledException)
                {
                    // Command was cancelled.
                }
            }
            else
            {
                throw new Exception("Test timeout: Cancellation didn't work.");
            }

            // Assert

            var shouldHaveRunTo = cancelAt <= configuredBoundary
                ? cancelAt
                : CancellationBoundary.CancelAlways; // Run to end

            await Validate(steps, shouldHaveRunTo);
        }
Example #7
0
 public Step(
     CancellationBoundary boundary,
     TaskCompletionSource <bool> completionSource,
     Func <Task <T> > validationFactory = null,
     Action <T> validateHasRun          = null,
     Action <T> validateHasNotRun       = null)
 {
     Boundary           = boundary;
     _completionSource  = completionSource;
     _validationFactory = validationFactory ?? (() => Task.FromResult(default(T)));
     _validateHasRun    = validateHasRun ?? (_ => { });
     _validateHasNotRun = validateHasNotRun ?? (_ => { });
 }
Example #8
0
 private static async Task Validate(IEnumerable <IStep> steps, CancellationBoundary shouldHaveRunTo)
 {
     foreach (var step in steps)
     {
         if (step.Boundary <= shouldHaveRunTo)
         {
             await step.ValidateHasRunAsync();
         }
         else
         {
             await step.ValidateHasNotRunAsync();
         }
     }
 }
 public static CancellationToken Limit(this ICancellationConfiguration configuration, CancellationToken token, CancellationBoundary currentBoundary)
 {
     token.ThrowIfCancellationRequested();
     return(currentBoundary < configuration.CancellationBoundary ? token : CancellationToken.None);
 }