Exemple #1
0
        public async Task <MessageRelayConnection> SelectNextConnectionAsync()
        {
            IReadOnlyList <MessageRelayRecord> allRecords = await this.messageRelayRecords.GetAllMessageRelayRecordsAsync();


            if (allRecords.Count == 0)
            {
                this.logger.LogWarning("No relay addresses in the store - can't select a connection candidate!");
                return(null);
            }

            // peers, shortest success ago first
            var hottestRecords = allRecords
                                 .Where(x => !IsExcluded(x))                                    // e.g. if we are already connected, or the last error is less than a certain time ago
                                 .OrderBy(x => DateTimeOffset.UtcNow - x.LastSeenUtc)           // then, try the best candidates first
                                 .ThenByDescending(x => DateTimeOffset.UtcNow - x.LastErrorUtc) // then, try the candidates where the last error is longest ago
                                 .ToList();

            if (hottestRecords.Count == 0)
            {
                this.logger.LogDebug("After applying the filtering rules, no connection candidates remain for selection.");
                return(null);
            }

            MessageRelayRecord messageRelayRecord = hottestRecords[0];

            this.logger.LogDebug($"Selected connection candidate {messageRelayRecord}, last seen {DateTimeOffset.UtcNow - messageRelayRecord.LastSeenUtc} ago, last error {DateTimeOffset.UtcNow - messageRelayRecord.LastErrorUtc} ago.");
            var  messageRelayConnection = new MessageRelayConnection(messageRelayRecord, this.cancellation.Token);
            bool addSuccess             = this.connections.TryAdd(messageRelayRecord.Id, messageRelayConnection);

            Debug.Assert(addSuccess, $"Bug: Peer {messageRelayRecord} was already in the ConnectedPeers dictionary - that should not happen.");
            return(messageRelayConnection);
        }
Exemple #2
0
 public MessageRelayConnection(MessageRelayRecord messageMessageRelayRecord, CancellationToken cancellationToken)
 {
     this.MessageRelayRecord = messageMessageRelayRecord;
     this.TcpClient          = new TcpClient(AddressFamily.InterNetworkV6);
     this.TcpClient.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
     this.cancellationToken = cancellationToken;
 }
Exemple #3
0
        bool IsExcluded(MessageRelayRecord relay)
        {
            if (this.connections.ContainsKey(relay.Id))
            {
                this.logger.LogDebug($"Peer {relay} is excluded, because it's in the list of connected peers.");
                return(true);
            }

            if (relay.LastErrorUtc != default)
            {
                var timeSinceLastError = DateTimeOffset.UtcNow - relay.LastErrorUtc;
                if (timeSinceLastError <= TimeSpan.FromSeconds(60))
                {
                    this.logger.LogDebug(
                        $"Peer (MessageRelay) {relay} is excluded, because it's last error is only {timeSinceLastError} ago.");
                    return(true);
                }
            }

            return(false);
        }