Ejemplo n.º 1
0
        /// <inheritdoc />
        public async Task <IImmutableList <Message> > FetchMessagesAsync(string topicName, int partitionId, long offset, int maxCount, CancellationToken cancellationToken)
        {
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), offset, "must be >= 0");
            }

            // Previously fetched messages may contain everything we need
            var localIndex = _localMessages.FindIndex(m => m.Offset == offset);

            if (0 <= localIndex && localIndex + maxCount <= _localMessages.Count)
            {
                return(_localMessages.GetRange(localIndex, maxCount));
            }

            var localCount = (0 <= localIndex && localIndex < _localMessages.Count) ? _localMessages.Count - localIndex : 0;
            var request    = new FetchRequest(new FetchRequest.Topic(topicName, partitionId, offset + localCount, Configuration.MaxPartitionFetchBytes),
                                              Configuration.MaxFetchServerWait, Configuration.MinFetchBytes, Configuration.MaxFetchBytes);
            var response = await _brokerRouter.SendAsync(request, topicName, partitionId, cancellationToken).ConfigureAwait(false);

            var topic = response.Topics.SingleOrDefault();

            if (topic?.Messages?.Count == 0)
            {
                return(ImmutableList <Message> .Empty);
            }

            if (localCount > 0)
            {
                // Previously fetched messages contain some of what we need, so append
                _localMessages = (ImmutableList <Message>)_localMessages.AddNotNullRange(topic?.Messages);
            }
            else
            {
                localIndex     = 0;
                _localMessages = topic?.Messages?.ToImmutableList() ?? ImmutableList <Message> .Empty;
            }
            return(_localMessages.GetRange(localIndex, Math.Min(maxCount, _localMessages.Count)));
        }