示例#1
0
        /// <summary>
        ///   Ask the next peer the question.
        /// </summary>
        async Task AskAsync(int taskId)
        {
            int pass  = 0;
            int waits = 20;

            while (!runningQuery.IsCancellationRequested && waits > 0)
            {
                // Get the nearest peer that has not been visited.
                var peer = Dht.RoutingTable
                           .NearestPeers(QueryKey)
                           .Where(p => !visited.Contains(p))
                           .FirstOrDefault();
                if (peer == null)
                {
                    --waits;
                    await Task.Delay(100);

                    continue;
                }

                ++pass;
                visited.Add(peer);

                // Ask the nearest peer.
                await askCount.WaitAsync(runningQuery.Token).ConfigureAwait(false);

                var start = DateTime.Now;
                log.Debug($"Q{Id}.{taskId}.{pass} ask {peer}");
                try
                {
                    using (var timeout = new CancellationTokenSource(askTime))
                        using (var cts = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, runningQuery.Token))
                            using (var stream = await Dht.Swarm.DialAsync(peer, Dht.ToString(), cts.Token).ConfigureAwait(false))
                            {
                                // Send the KAD query and get a response.
                                ProtoBuf.Serializer.SerializeWithLengthPrefix(stream, queryMessage, PrefixStyle.Base128);
                                await stream.FlushAsync(cts.Token).ConfigureAwait(false);

                                var response = await ProtoBufHelper.ReadMessageAsync <DhtMessage>(stream, cts.Token).ConfigureAwait(false);

                                // Process answer
                                ProcessProviders(response.ProviderPeers);
                                ProcessCloserPeers(response.CloserPeers);
                            }
                    var time = DateTime.Now - start;
                    log.Debug($"Q{Id}.{taskId}.{pass} ok {peer} ({time.TotalMilliseconds} ms)");
                }
                catch (Exception e)
                {
                    Interlocked.Increment(ref failedConnects);
                    var time = DateTime.Now - start;
                    log.Warn($"Q{Id}.{taskId}.{pass} failed ({time.TotalMilliseconds} ms) - {e.Message}");
                    // eat it
                }
                finally
                {
                    askCount.Release();
                }
            }
        }
示例#2
0
        /// <summary>
        ///   Ask the next peer the question.
        /// </summary>
        async Task AskAsync(int taskId)
        {
            int pass = 0;

            while (!runningQuery.IsCancellationRequested)
            {
                ++pass;

                // Get the nearest peer that has not been visited.
                var peer = Dht.RoutingTable
                           .NearestPeers(QueryKey)
                           .Where(p => !visited.Contains(p))
                           .FirstOrDefault();
                if (peer == null)
                {
                    return;
                }
                visited.Add(peer);

                // Ask the nearest peer.
                try
                {
                    await askCount.WaitAsync(runningQuery.Token);

                    log.Debug($"Q{Id}.{taskId}.{pass} ask {peer}");
                    using (var timeout = new CancellationTokenSource(askTime))
                        using (var cts = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, runningQuery.Token))
                            using (var stream = await Dht.Swarm.DialAsync(peer, Dht.ToString(), cts.Token))
                            {
                                // Send the KAD query and get a response.
                                ProtoBuf.Serializer.SerializeWithLengthPrefix(stream, queryMessage, PrefixStyle.Base128);
                                await stream.FlushAsync(cts.Token);

                                var response = await ProtoBufHelper.ReadMessageAsync <DhtMessage>(stream, cts.Token);

                                // Process answer
                                ProcessProviders(response.ProviderPeers);
                                ProcessCloserPeers(response.CloserPeers);
                            }
                }
                catch (Exception e)
                {
                    log.Warn($"Q{Id}.{taskId}.{pass} ask failed {e.Message}");
                    // eat it
                }
                finally
                {
                    askCount.Release();
                }
            }
        }