コード例 #1
0
        public static StreamCoordinates SetPosition(this StreamCoordinates coordinates, StreamPosition position)
        {
            var dict = coordinates.ToDictionary();

            dict[position.Partition] = position;
            return(new StreamCoordinates(dict.Values.ToArray()));
        }
コード例 #2
0
 public StreamSegmentReaderSettings(
     [NotNull] string streamName,
     [NotNull] IHerculesStreamClient <T> streamClient,
     [NotNull] StreamCoordinates start,
     [NotNull] StreamCoordinates end)
 {
     StreamName   = streamName;
     StreamClient = streamClient;
     Start        = start.ToDictionary();
     End          = end.ToDictionary();
 }
コード例 #3
0
        /// <summary>
        /// Filter by next partitions.
        /// </summary>
        public static StreamCoordinates FilterBy([NotNull] this StreamCoordinates left, [NotNull] StreamCoordinates right)
        {
            var map    = left.ToDictionary();
            var result = new List <StreamPosition>();

            foreach (var position in right.Positions)
            {
                if (map.TryGetValue(position.Partition, out var was))
                {
                    result.Add(was);
                }
            }

            return(new StreamCoordinates(result.ToArray()));
        }
コード例 #4
0
        public static long DistanceTo([NotNull] this StreamCoordinates from, [NotNull] StreamCoordinates to)
        {
            var map    = from.ToDictionary();
            var result = 0L;

            foreach (var position in to.Positions)
            {
                if (map.TryGetValue(position.Partition, out var p))
                {
                    result += position.Offset - p.Offset;
                }
                else
                {
                    result += position.Offset;
                }
            }

            return(result);
        }
コード例 #5
0
        public static bool AdvancesOver([NotNull] this StreamCoordinates self, [NotNull] StreamCoordinates other)
        {
            var otherDictionary = other.ToDictionary();

            foreach (var position in self.Positions)
            {
                if (!otherDictionary.TryGetValue(position.Partition, out var otherPosition))
                {
                    return(true);
                }

                if (position.Offset > otherPosition.Offset)
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #6
0
        public static StreamCoordinates MergeMinWith([NotNull] this StreamCoordinates left, [NotNull] StreamCoordinates right)
        {
            var map = left.ToDictionary();

            foreach (var position in right.Positions)
            {
                if (!map.TryGetValue(position.Partition, out var currentPosition))
                {
                    map[position.Partition] = position;
                }
                else
                {
                    map[position.Partition] = new StreamPosition
                    {
                        Partition = position.Partition,
                        Offset    = Math.Min(position.Offset, currentPosition.Offset)
                    };
                }
            }

            return(new StreamCoordinates(map.Values.ToArray()));
        }
コード例 #7
0
        public async Task <(ReadStreamQuery query, ReadStreamResult <T> result)> ReadAsync(
            StreamCoordinates coordinates,
            StreamShardingSettings shardingSettings,
            CancellationToken cancellationToken)
        {
            log.Info(
                "Reading logical shard with index {ClientShard} from {ClientShardCount}.",
                shardingSettings.ClientShardIndex,
                shardingSettings.ClientShardCount);

            log.Debug("Current coordinates: {StreamCoordinates}.", coordinates);

            coordinates = await GetShardCoordinates(coordinates, shardingSettings, cancellationToken).ConfigureAwait(false);

            log.Debug("Current shard coordinates: {StreamCoordinates}.", coordinates);

            streamPartitionsCount = streamPartitionsCount ?? await GetPartitionsCount(cancellationToken).ConfigureAwait(false);

            var current = coordinates.ToDictionary();

            foreach (var partition in coordinates.Positions.Select(p => p.Partition))
            {
                var start = current.ContainsKey(partition) ? current[partition].Offset : 0;
                var end   = settings.End.ContainsKey(partition) ? settings.End[partition].Offset : 0;

                if (start < end)
                {
                    var count = end - start;

                    log.Info("Reading {EventsCount} events from partition #{Partition}.", count, partition);

                    var(query, result) = await streamReader.ReadAsync(
                        coordinates,
                        // ReSharper disable once PossibleInvalidOperationException
                        new StreamShardingSettings(partition, streamPartitionsCount.Value),
                        count,
                        cancellationToken)
                                         .ConfigureAwait(false);

                    result.EnsureSuccess();

                    result = new ReadStreamResult <T>(
                        result.Status,
                        new ReadStreamPayload <T>(
                            result.Payload.Events,
                            coordinates.SetPosition(result.Payload.Next.Positions.Single())),
                        result.ErrorDetails);

                    query = new ReadStreamQuery(query.Name)
                    {
                        Coordinates      = coordinates,
                        ClientShard      = shardingSettings.ClientShardIndex,
                        ClientShardCount = shardingSettings.ClientShardCount
                    };

                    return(query, result);
                }
            }

            return(null, null);
        }