// This updates routing table when receiving a message. // if corresponding bucket for remote peer is not full, just adds remote peer. // otherwise check whether if the least recently used (LRU) peer // is alive to determine evict LRU peer or discard remote peer. private async Task UpdateAsync( Peer rawPeer, CancellationToken cancellationToken = default(CancellationToken)) { if (rawPeer is null) { throw new ArgumentNullException(nameof(rawPeer)); } if (!(rawPeer is BoundPeer peer) || rawPeer.AppProtocolVersion != _appProtocolVersion) { // Don't update peer without endpoint or with different appProtocolVersion. return; } if (cancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } bool contains = _routing.Contains(peer); BoundPeer evictionCandidate = await _routing.AddPeerAsync(peer); if (evictionCandidate is null) { // added successfully since there was empty space in the bucket if (!contains) { _routing.BucketOf(peer).ReplacementCache.Remove(peer); _logger.Debug($"Added [{peer.Address.ToHex()}] to table"); } } else { _logger.Verbose( "Need to evict {Candidate}; trying...", evictionCandidate); try { if (!_routing.BucketOf(peer).ReplacementCache.Contains(peer)) { _routing.BucketOf(peer).ReplacementCache.Add(peer); } await PingAsync( evictionCandidate, _requestTimeout, cancellationToken); } catch (TimeoutException) { await RemovePeerAsync(evictionCandidate); _logger.Verbose( "Peer ({Candidate}) has been evicted.", evictionCandidate); } } }
// This updates routing table when receiving a message. // if corresponding bucket for remote peer is not full, just adds remote peer. // otherwise check whether if the least recently used (LRU) peer // is alive to determine evict LRU peer or discard remote peer. private async Task UpdateAsync( Peer rawPeer, CancellationToken cancellationToken = default(CancellationToken)) { if (rawPeer is null) { throw new ArgumentNullException(nameof(rawPeer)); } if (!(rawPeer is BoundPeer peer) || rawPeer.AppProtocolVersion != _appProtocolVersion) { // Don't update peer without endpoint or with different appProtocolVersion. return; } if (cancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } BoundPeer evictionCandidate = await _routing.AddPeerAsync(peer); if (!(evictionCandidate is null)) { _logger.Verbose( "Need to evict {Candidate}; trying...", evictionCandidate); try { await ValidateAsync( evictionCandidate, _requestTimeout, cancellationToken); } catch (TimeoutException) { _logger.Verbose( "Peer ({Candidate}) has been evicted.", evictionCandidate); } } }
// This updates routing table when receiving a message. // if corresponding bucket for remote peer is not full, just adds remote peer. // otherwise check whether if the least recently used (LRU) peer // is alive to determine evict LRU peer or discard remote peer. private async Task UpdateAsync( Peer rawPeer, CancellationToken cancellationToken = default(CancellationToken)) { if (rawPeer is null) { throw new ArgumentNullException(nameof(rawPeer)); } if (!(rawPeer is BoundPeer peer) || rawPeer.AppProtocolVersion != _appProtocolVersion) { // Don't update peer without endpoint or with different appProtocolVersion. return; } if (cancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } await _routing.AddPeerAsync(peer); }