Example #1
0
 private async Task Push(ReadAllPage page)
 {
     foreach (var message in page.Messages)
     {
         if (_disposed.IsCancellationRequested)
         {
             NotifySubscriptionDropped(SubscriptionDroppedReason.Disposed);
             _disposed.Token.ThrowIfCancellationRequested();
         }
         _nextPosition = message.Position + 1;
         LastPosition  = message.Position;
         try
         {
             await _streamMessageReceived(this, message).NotOnCapturedContext();
         }
         catch (Exception ex)
         {
             s_logger.ErrorException(
                 $"Exception with subscriber receiving message {Name}" +
                 $"Message: {message}.",
                 ex);
             NotifySubscriptionDropped(SubscriptionDroppedReason.SubscriberError, ex);
             throw;
         }
     }
 }
        private static ReadAllPage ReadAllBackwardsInternal(IHalClient client, bool prefetch)
        {
            var resource = client.Current.First();

            var pageInfo = resource.Data <HalReadAllPage>();

            var streamMessages = Convert(
                resource.Embedded
                .Where(r => r.Rel == Constants.Relations.Message)
                .ToArray(),
                client,
                prefetch);

            var readAllPage = new ReadAllPage(
                pageInfo.FromPosition,
                pageInfo.NextPosition,
                pageInfo.IsEnd,
                ReadDirection.Backward,
                async(position, cancellationToken) => ReadAllBackwardsInternal(
                    await client.GetAsync(resource, Constants.Relations.Previous, cancellationToken),
                    prefetch),
                streamMessages);

            return(readAllPage);
        }
Example #3
0
        private ReadAllPage Read(AllStreamPosition from)
        {
            var maxPosition = MaxPosition;

            _writeLine($"From {from}, Max {maxPosition}");
            if (from > MaxPosition)
            {
                var page = new ReadAllPage(from, from, true, new Envelope[0]);
                _writeLine(page.ToString());
                return(page);
            }
            var messages = Enumerable.Range(0, 10)
                           .Where(x => x <= maxPosition - from.ToInt64())
                           .Select(x => new Envelope(from.Shift(x), x))
                           .ToArray();
            bool isEnd  = !messages.Any() || messages.Last().Checkpoint.ToInt64() == maxPosition;
            var  result = new ReadAllPage(
                from,
                messages.Any() ? messages.Last().Checkpoint.Shift() : from,
                isEnd,
                messages);

            _writeLine(result.ToString());
            return(result);
        }
 public static Link Next(ReadAllPage page, ReadAllStreamOperation operation)
 => new Link(
     Constants.Relations.Next,
     LinkFormatter.FormatForwardLink(
         Constants.Streams.All,
         operation.MaxCount,
         page.Messages.Max(m => m.Position) + 1,
         operation.EmbedPayload));
 public static Link Previous(ReadAllPage page, ReadAllStreamOperation operation)
 => new Link(
     Constants.Relations.Previous,
     LinkFormatter.FormatBackwardLink(
         Constants.Streams.All,
         operation.MaxCount,
         page.Messages.Min(m => m.Position) - 1,
         operation.EmbedPayload));
            public static IEnumerable <Link> Navigation(ReadAllPage page, string self)
            {
                yield return(First);

                if (self != First.Href && !page.IsEnd)
                {
                    yield return(Previous(page));
                }

                if (self != Last.Href && !page.IsEnd)
                {
                    yield return(Next(page));
                }

                yield return(Last);
            }
Example #7
0
        public static Links AllStreamNavigation(
            this Links links,
            ReadAllPage page,
            ReadAllStreamOperation operation)
        {
            var first = Links.FormatForwardLink(
                Constants.Streams.All,
                operation.MaxCount,
                Position.Start,
                operation.EmbedPayload);

            var last = Links.FormatBackwardLink(
                Constants.Streams.All,
                operation.MaxCount,
                Position.End,
                operation.EmbedPayload);

            links.Add(Constants.Relations.First, first);

            if (operation.Self != first && !page.IsEnd)
            {
                links.Add(
                    Constants.Relations.Previous,
                    Links.FormatBackwardLink(
                        Constants.Streams.All,
                        operation.MaxCount,
                        page.Messages.Min(m => m.Position) - 1,
                        operation.EmbedPayload));
            }

            links.Add(Constants.Relations.Feed, operation.Self).Self();

            if (operation.Self != last && !page.IsEnd)
            {
                links.Add(
                    Constants.Relations.Next,
                    Links.FormatForwardLink(
                        Constants.Streams.All,
                        operation.MaxCount,
                        page.Messages.Max(m => m.Position) + 1,
                        operation.EmbedPayload));
            }

            links.Add(Constants.Relations.Last, last);

            return(links);
        }
Example #8
0
        private async Task <ReadAllPage> FilterExpired(
            ReadAllPage readAllPage,
            ReadNextAllPage readNext,
            CancellationToken cancellationToken)
        {
            if (_disableMetadataCache)
            {
                return(readAllPage);
            }
            var valid      = new List <StreamMessage>();
            var currentUtc = GetUtcNow();

            foreach (var streamMessage in readAllPage.Messages)
            {
                if (streamMessage.StreamId.StartsWith("$"))
                {
                    valid.Add(streamMessage);
                    continue;
                }
                int?maxAge = _metadataMaxAgeCache == null
                    ? null
                    : await _metadataMaxAgeCache.GetMaxAge(streamMessage.StreamId, cancellationToken);

                if (!maxAge.HasValue)
                {
                    valid.Add(streamMessage);
                    continue;
                }
                if (streamMessage.CreatedUtc.AddSeconds(maxAge.Value) > currentUtc)
                {
                    valid.Add(streamMessage);
                }
                else
                {
                    PurgeExpiredMessage(streamMessage);
                }
            }
            return(new ReadAllPage(
                       readAllPage.FromPosition,
                       readAllPage.NextPosition,
                       readAllPage.IsEnd,
                       readAllPage.Direction,
                       readNext,
                       valid.ToArray()));
        }
            public static IEnumerable <Link> Navigation(ReadAllPage page, ReadAllStreamOperation operation)
            {
                var first = First(operation);
                var last  = Last(operation);

                yield return(first);

                if (operation.Self != first.Href && !page.IsEnd)
                {
                    yield return(Previous(page, operation));
                }

                if (operation.Self != last.Href && !page.IsEnd)
                {
                    yield return(Next(page, operation));
                }

                yield return(last);
            }
Example #10
0
        public static bool TryGetETag(this ReadAllPage page, long fromPosition, out ETag eTag)
        {
            if (page.Direction == ReadDirection.Backward && fromPosition == Position.End)
            {
                eTag = ETag.FromPosition(page.Messages.Length > 0 ? page.Messages[0].Position : Position.End);
                return(true);
            }

            if (page.IsEnd && page.Direction == ReadDirection.Forward)
            {
                eTag = ETag.FromPosition(page.Messages.Length > 0 ? page.Messages[page.Messages.Length - 1].Position : Position.End);
                return(true);
            }

            if (page.IsEnd && page.Direction == ReadDirection.Backward)
            {
                eTag = ETag.FromPosition(page.Messages.Length > 0 ? page.Messages[0].Position : Position.End);
                return(true);
            }

            eTag = ETag.None;

            return(false);
        }
        protected override Task <ReadAllPage> ReadAllBackwardsInternal(
            long fromPositionExclusive,
            int maxCount,
            bool prefetch,
            ReadNextAllPage readNext,
            CancellationToken cancellationToken)
        {
            GuardAgainstDisposed();

            using (_lock.UseReadLock())
            {
                if (fromPositionExclusive == Position.End)
                {
                    fromPositionExclusive = _allStream.Last.Value.Position;
                }

                // Find the node to start from (it may not be equal to the exact position)
                var current = _allStream.First;
                if (current.Next == null) //Empty store
                {
                    var result = new ReadAllPage(Position.Start, Position.Start, true, ReadDirection.Backward,
                                                 StreamMessage.EmptyArray, readNext);
                    return(Task.FromResult(result));
                }

                var previous = current.Previous;
                while (current.Value.Position < fromPositionExclusive)
                {
                    if (current.Next == null) // fromPosition is past end of store
                    {
                        var result = new ReadAllPage(fromPositionExclusive, fromPositionExclusive, true,
                                                     ReadDirection.Backward, StreamMessage.EmptyArray, readNext);
                        return(Task.FromResult(result));
                    }
                    previous = current;
                    current  = current.Next;
                }

                var messages = new List <StreamMessage>();
                while (maxCount > 0 && current != _allStream.First)
                {
                    StreamMessage message;
                    if (prefetch)
                    {
                        message = new StreamMessage(
                            current.Value.StreamId,
                            current.Value.MessageId,
                            current.Value.StreamVersion,
                            current.Value.Position,
                            current.Value.Created,
                            current.Value.Type,
                            current.Value.JsonMetadata,
                            current.Value.JsonData);
                    }
                    else
                    {
                        var currentCopy = current;
                        message = new StreamMessage(
                            current.Value.StreamId,
                            current.Value.MessageId,
                            current.Value.StreamVersion,
                            current.Value.Position,
                            current.Value.Created,
                            current.Value.Type,
                            current.Value.JsonMetadata,
                            ct =>
                        {
                            return(Task.Run(
                                       () => ReadMessageData(currentCopy.Value.StreamId, currentCopy.Value.MessageId), ct));
                        });
                    }
                    messages.Add(message);

                    maxCount--;
                    previous = current;
                    current  = current.Previous;
                }

                bool isEnd;
                if (previous == null || previous.Value.Position == 0)
                {
                    isEnd = true;
                }
                else
                {
                    isEnd = false;
                }
                var nextCheckPoint = isEnd
                    ? 0
                    : current.Value.Position;

                fromPositionExclusive = messages.Any() ? messages[0].Position : 0;

                var page = new ReadAllPage(
                    fromPositionExclusive,
                    nextCheckPoint,
                    isEnd,
                    ReadDirection.Backward,
                    messages.ToArray(),
                    readNext);

                return(Task.FromResult(page));
            }
        }
 public static Link Next(ReadAllPage page)
 => new Link(Relations.Next,
             LinkFormatter.FormatForwardLink(StreamId, 20, page.Messages.Max(m => m.Position) + 1));
 public static Link Previous(ReadAllPage page)
 => new Link(Relations.Previous,
             LinkFormatter.FormatBackwardLink(StreamId, 20, page.Messages.Min(m => m.Position) - 1));