示例#1
0
        public void new_subscription_should_be_healthy()
        {
            var subscription = new LambdaSubscription(_empty);

            Assert.False(subscription.ReadCompleted);
            Assert.False(subscription.Failed);
            Assert.Null(subscription.LastError);
            Assert.Equal(0, subscription.FailedPosition);
        }
示例#2
0
        public async Task should_track_errors()
        {
            var subscription = new LambdaSubscription(_empty);

            var ex = new Exception("message");
            await subscription.OnErrorAsync(1, ex);

            Assert.True(subscription.Failed);
            Assert.Same(ex, subscription.LastError);
            Assert.Equal(1, subscription.FailedPosition);
        }
示例#3
0
        public exceptions_should_be_signaled()
        {
            // write stream out of order to have
            // position 1 : index 2
            // position 2 : index 1
            //
            Store.AppendAsync("a", 2, "data b").GetAwaiter().GetResult();
            Store.AppendAsync("a", 1, "data a").GetAwaiter().GetResult();

            _subscription = new LambdaSubscription(_throw);
        }
示例#4
0
        public async Task <long> GetEventsAsync(string actorName, long indexStart, long indexEnd, Action <object> callback)
        {
            long lastIndex = -1;
            var  adapter   = new LambdaSubscription(chunk =>
            {
                lastIndex = chunk.Index;
                callback(chunk.Payload);
                return(Task.FromResult(true));
            });

            await _events.ReadForwardAsync(actorName, indexStart, adapter, indexEnd).ConfigureAwait(false);

            return(lastIndex); // TODO -> check sources, not really needed imho
        }
示例#5
0
        public async Task should_call_on_start_delegate()
        {
            long trackedPosition = 0;
            var  subscription    = new LambdaSubscription(_empty)
            {
                OnStart = position =>
                {
                    trackedPosition = position;
                    return(Task.CompletedTask);
                }
            };

            await subscription.OnStartAsync(1);

            Assert.Equal(1, trackedPosition);
        }
示例#6
0
        public async Task should_call_on_complete_delegate()
        {
            long trackedPosition = 0;
            var  subscription    = new LambdaSubscription(_empty)
            {
                OnComplete = position =>
                {
                    trackedPosition = position;
                    return(Task.CompletedTask);
                }
            };

            await subscription.CompletedAsync(1);

            Assert.Equal(1, trackedPosition);
            Assert.True(subscription.ReadCompleted);
        }
示例#7
0
        public async Task should_call_on_stop_delegate()
        {
            long trackedPosition = 0;
            var  subscription    = new LambdaSubscription(_empty)
            {
                OnStop = position =>
                {
                    trackedPosition = position;
                    return(Task.CompletedTask);
                }
            };

            await subscription.StoppedAsync(1).ConfigureAwait(false);

            Assert.Equal(1, trackedPosition);
            Assert.True(subscription.ReadCompleted);
        }
示例#8
0
        public async Task should_intercept_on_error()
        {
            Exception trackedException = null;
            long      trackedPosition  = 0;
            var       subscription     = new LambdaSubscription(_empty)
            {
                OnError = (position, exception) =>
                {
                    trackedException = exception;
                    trackedPosition  = position;
                    return(Task.CompletedTask);
                }
            };

            var ex = new Exception("message");
            await subscription.OnErrorAsync(1, ex);

            Assert.True(subscription.Failed);
            Assert.Same(ex, trackedException);
            Assert.Equal(1, trackedPosition);
        }
示例#9
0
        public subscription_events_should_be_signaled()
        {
            // write stream out of order to have
            // position 1 : index 2
            // position 2 : index 1
            //
            Store.AppendAsync("a", 2, "data b").GetAwaiter().GetResult();
            Store.AppendAsync("a", 1, "data a").GetAwaiter().GetResult();

            _subscription = new LambdaSubscription(_continueToEnd)
            {
                OnStart = p =>
                {
                    _startedAt = p;
                    return(Task.CompletedTask);
                },
                OnComplete = p =>
                {
                    _completedAt = p;
                    return(Task.CompletedTask);
                }
            };
        }
示例#10
0
        private void Add(List <LambdaSubscription> subscriptions, S3SubscriptionProperties properties)
        {
            foreach (var filter in properties.Filters)
            {
                var subscription = new LambdaSubscription {
                    FunctionArn = properties.Function,
                    Events      = filter.Events.Select(e => EventType.FindValue(e)).ToList()
                };

                // check if prefix/suffix filter were provided
                if ((filter.Prefix != null) || (filter.Suffix != null))
                {
                    var rules = new List <FilterRule>();
                    if (filter.Prefix != null)
                    {
                        rules.Add(new FilterRule {
                            Name  = "prefix",
                            Value = filter.Prefix
                        });
                    }
                    if (filter.Suffix != null)
                    {
                        rules.Add(new FilterRule {
                            Name  = "suffix",
                            Value = filter.Suffix
                        });
                    }
                    subscription.Filter = new LambdaFilter {
                        S3KeyFilter = new S3KeyFilter {
                            FilterRules = rules
                        }
                    };
                }
                subscriptions.Add(subscription);
            }
        }
示例#11
0
        public async Task <IAggregate> GetByIdAsync(Type aggregateType, string id, CancellationToken cancellationToken)
        {
            if (_trackingAggregates.TryGetValue(id, out IAggregate aggregate))
            {
                return(aggregate);
            }

            aggregate = _factory.Create(aggregateType);
            var persister = (IEventSourcedAggregate)aggregate;

            SnapshotInfo snapshot = null;

            if (_snapshots != null && aggregate is ISnapshottable snapshottable)
            {
                snapshot = await _snapshots.GetLastAsync(id, cancellationToken).ConfigureAwait(false);

                if (snapshot != null)
                {
                    //@@REVIEW: invalidate snapshot on false?
                    snapshottable.TryRestore(snapshot);
                }
            }

            if (!aggregate.IsInitialized)
            {
                aggregate.Init(id);
            }

            _trackingAggregates.Add(id, aggregate);
            var stream = OpenStream(id);

            int readCount    = 0;
            var subscription = new LambdaSubscription(data =>
            {
                readCount++;
                persister.ApplyChanges((Changeset)data.Payload);
                return(Task.FromResult(true));
            });
            var consumer = ConfigureConsumer(subscription, cancellationToken);

            // we use aggregate.Version because snapshot could be rejected
            // Starting point is inclusive, so almost one changeset should be loaded
            // aggregate will ignore because ApplyChanges is idempotent
            await stream.ReadAsync(consumer, aggregate.Version, long.MaxValue, cancellationToken).ConfigureAwait(false);

            //Check lambda subscription for errors.
            if (subscription.Failed)
            {
                throw new RepositoryReadException($"Error reading aggregate {id}", subscription.LastError);
            }

            persister.Loaded();

            // no data from stream, we cannot validate the aggregate
            if (snapshot != null && readCount == 0)
            {
                throw new StaleSnapshotException(snapshot.SourceId, snapshot.SourceVersion);
            }

            return(aggregate);
        }