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); }
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); }
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); }
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); }
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));