private async Task ProcessDeltaAsync(CancellationToken cancellationToken) { while (true) { PeerSetDelta delta; while (!_deltas.TryDequeue(out delta, TimeSpan.FromMilliseconds(100))) { await Task.Delay(100, cancellationToken); } Peer sender = delta.Sender; PublicKey senderKey = sender.PublicKey; if (!_peers.ContainsKey(sender) && _peers.Keys.All(p => senderKey != p.PublicKey)) { delta = new PeerSetDelta( delta.Sender, delta.Timestamp, delta.AddedPeers.Add(sender), delta.RemovedPeers, delta.ExistingPeers ); } _logger.Debug($"Received the delta[{delta}]."); using (await _receiveMutex.LockAsync(cancellationToken)) { DeltaReceived.Reset(); _logger.Debug($"Trying to apply the delta[{delta}]..."); await ApplyDelta(delta, cancellationToken); LastReceived = delta.Timestamp; LastSeenTimestamps[delta.Sender] = delta.Timestamp; DeltaReceived.Set(); } _logger.Debug($"The delta[{delta}] has been applied."); } }
private async Task ApplyDelta(PeerSetDelta delta, CancellationToken cancellationToken) { PublicKey senderPublicKey = delta.Sender.PublicKey; bool firstEncounter = _peers.Keys.All(p => p.PublicKey != senderPublicKey); RemovePeers(delta.RemovedPeers, delta.Timestamp); var addedPeers = new HashSet <Peer>(delta.AddedPeers); if (delta.ExistingPeers != null) { ImmutableHashSet <PublicKey> removedPublicKeys = _removedPeers .Keys.Select(p => p.PublicKey) .ToImmutableHashSet(); addedPeers.UnionWith( delta.ExistingPeers.Where( p => !removedPublicKeys.Contains(p.PublicKey) ) ); } _logger.Debug("Trying to add peers..."); ISet <Peer> added = await AddPeersAsync( addedPeers, delta.Timestamp, cancellationToken); if (_logger.IsEnabled(LogEventLevel.Debug)) { DumpDiffs( delta, added, addedPeers.Except(added), delta.RemovedPeers ); } if (firstEncounter) { await DistributeDeltaAsync(true, cancellationToken); } }
private void DumpDiffs( PeerSetDelta delta, IEnumerable <Peer> added, IEnumerable <Peer> existing, IEnumerable <Peer> removed) { DateTime timestamp = delta.Timestamp; foreach (Peer peer in added) { _logger.Debug($"{timestamp} {delta.Sender} > +{peer}"); } foreach (Peer peer in existing) { _logger.Debug($"{timestamp} {delta.Sender} > {peer}"); } foreach (Peer peer in removed) { _logger.Debug($"{timestamp} {delta.Sender} > -{peer}"); } }