Пример #1
0
        private void GossipTo(Address address)
        {
            var to = Replica(address);

            if (_dataEntries.Count <= _settings.MaxDeltaElements)
            {
                var status = new Internal.Status(_dataEntries.Select(x => new KeyValuePair <string, ByteString>(x.Key, GetDigest(x.Key))).ToImmutableDictionary(), 0, 1);
                to.Tell(status);
            }
            else
            {
                var totChunks = _dataEntries.Count / _settings.MaxDeltaElements;
                for (var i = 1; i <= Math.Min(totChunks, 10); i++)
                {
                    if (totChunks == _statusTotChunks)
                    {
                        _statusCount++;
                    }
                    else
                    {
                        _statusCount     = ThreadLocalRandom.Current.Next(0, totChunks);
                        _statusTotChunks = totChunks;
                    }
                    var chunk   = (int)(_statusCount % totChunks);
                    var entries = _dataEntries.Where(x => Math.Abs(x.Key.GetHashCode()) % totChunks == chunk)
                                  .Select(x => new KeyValuePair <string, ByteString>(x.Key, GetDigest(x.Key)))
                                  .ToImmutableDictionary();
                    var status = new Internal.Status(entries, chunk, totChunks);
                    to.Tell(status);
                }
            }
        }
Пример #2
0
        private Proto.Msg.Status StatusToProto(Status status)
        {
            var proto = new Proto.Msg.Status
            {
                Chunk     = (uint)status.Chunk,
                TotChunks = (uint)status.TotalChunks
            };

            foreach (var entry in status.Digests)
            {
                proto.Entries.Add(new Proto.Msg.Status.Types.Entry
                {
                    Key    = entry.Key,
                    Digest = ByteString.CopyFrom(entry.Value.ToByteArray())
                });
            }

            if (status.ToSystemUid.HasValue)
            {
                proto.HasToSystemUid = true;
                proto.ToSystemUid    = status.ToSystemUid.Value;
            }

            if (status.FromSystemUid.HasValue)
            {
                proto.HasFromSystemUid = true;
                proto.FromSystemUid    = status.FromSystemUid.Value;
            }

            return(proto);
        }
Пример #3
0
        private void ReceiveStatus(IImmutableDictionary <string, ByteString> otherDigests, int chunk, int totChunks)
        {
            if (_log.IsDebugEnabled)
            {
                _log.Debug("Received gossip status from {0}, chunk {1} of {2} containing {3}", Sender.Path.Address, chunk, totChunks, string.Join(", ", otherDigests.Keys));
            }

            var otherDifferentKeys = otherDigests
                                     .Where(x => IsOtherDifferent(x.Key, x.Value))
                                     .Select(x => x.Key)
                                     .ToArray();

            var otherKeys = otherDigests.Keys.ToImmutableHashSet();
            var myKeys    = (totChunks == 1
                ? _dataEntries.Keys
                : _dataEntries.Keys.Where(x => x.GetHashCode() % totChunks == chunk))
                            .ToImmutableHashSet();

            var otherMissingKeys = myKeys.Except(otherKeys);

            var keys = otherDifferentKeys
                       .Union(otherMissingKeys)
                       .Take(_settings.MaxDeltaElements)
                       .ToArray();

            if (keys.Length != 0)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("Sending gossip to {0}, containing {1}", Sender.Path.Address, string.Join(", ", keys));
                }

                var g = new Gossip(keys.Select(k => new KeyValuePair <string, DataEnvelope>(k, GetData(k))).ToImmutableDictionary(), otherDifferentKeys.Any());
                Sender.Tell(g);
            }

            var myMissingKeys = otherKeys.Except(myKeys);

            if (!myMissingKeys.IsEmpty)
            {
                if (Context.System.Log.IsDebugEnabled)
                {
                    Context.System.Log.Debug("Sending gossip status to {0}, requesting missing {1}", Sender.Path.Address, string.Join(", ", myMissingKeys));
                }

                var status = new Internal.Status(myMissingKeys.Select(x => new KeyValuePair <string, ByteString>(x, NotFoundDigest)).ToImmutableDictionary(), chunk, totChunks);
                Sender.Tell(status);
            }
        }