private async Task <AllMessagesPage> FilterExpired( AllMessagesPage allMessagesPage, CancellationToken cancellationToken) { var valid = new List <StreamMessage>(); var currentUtc = GetUtcNow(); foreach (var streamMessage in allMessagesPage.Messages) { if (streamMessage.StreamId.StartsWith("$")) { valid.Add(streamMessage); continue; } var maxAge = 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 AllMessagesPage( allMessagesPage.FromPosition, allMessagesPage.NextPosition, allMessagesPage.IsEnd, allMessagesPage.Direction, valid.ToArray())); }
protected override Task <AllMessagesPage> ReadAllBackwardsInternal( long fromPositionExclusive, int maxCount, 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 { return(Task.FromResult( new AllMessagesPage(Position.Start, Position.Start, true, ReadDirection.Backward))); } var previous = current.Previous; while (current.Value.Position < fromPositionExclusive) { if (current.Next == null) // fromPosition is past end of store { return(Task.FromResult( new AllMessagesPage(fromPositionExclusive, fromPositionExclusive, true, ReadDirection.Backward))); } previous = current; current = current.Next; } var messages = new List <StreamMessage>(); while (maxCount > 0 && current != _allStream.First) { var message = new StreamMessage( current.Value.StreamId, current.Value.MessageId, current.Value.StreamVersion, current.Value.Position, current.Value.Created, current.Value.Type, current.Value.JsonData, current.Value.JsonMetadata); 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 AllMessagesPage( fromPositionExclusive, nextCheckPoint, isEnd, ReadDirection.Backward, messages.ToArray()); return(Task.FromResult(page)); } }