async Task <long> ConnectAsync()
        {
            var message = new ConnectMessage();

            // Reset the timer so we don't do two concurrent connect requests. It's just an optimisation
            // as concurrent requests are fine!
            LastConnected.Restart();

            // Send our request, which could take a few retries.
            (var rawResponse, var errorString) = await SendAndReceiveAsync(message);

            // Did we receive an 'ErrorMessage' from the tracker? If so, propagate the failure
            if (errorString != null)
            {
                ConnectionIdTask = null;
                throw new TrackerException(errorString);
            }

            var response = (ConnectResponseMessage)rawResponse;

            // Reset the timer after we receive the response so we get maximum benefit from our
            // 2 minute allowance to use the connection id.
            LastConnected.Restart();
            return(response.ConnectionId);
        }
Beispiel #2
0
        void InitializeTyrant()
        {
            HaveMessageEstimatedDownloadedBytes = 0;
            TyrantStartTime.Restart();

            UploadRateForRecip = MARKET_RATE;
            LastRateReductionTime.Restart();
            lastMeasuredDownloadRate = 0;

            maxObservedDownloadSpeed = 0;
            RoundsChoked             = 0;
            RoundsUnchoked           = 0;
        }
Beispiel #3
0
        public async ReusableTask <AnnounceResponse> AnnounceAsync(AnnounceRequest parameters, CancellationToken token)
        {
            try {
                StatusOverride = TrackerState.Connecting;
                var response = LastAnnounceResponse = await Connection.AnnounceAsync(parameters, token);

                LastResponse = response;
                return(response);
            } finally {
                StatusOverride = null;
                LastAnnounced.Restart();
            }
        }
        async Task Announce(TorrentEvent clientEvent, ITracker referenceTracker)
        {
            // If the user initiates an Announce we need to go to the correct thread to process it.
            await ClientEngine.MainLoop;

            LastAnnounce.Restart();
            LastUpdated = DateTime.UtcNow;

            var p = RequestFactory.CreateAnnounce(clientEvent);

            foreach (var tuple in GetNextTracker(referenceTracker))
            {
                try {
                    // If we have not announced to this Tracker tier yet then we should replace the ClientEvent.
                    // But if we end up announcing to a different Tracker tier we may want to send the
                    // original/unmodified args.
                    var actualArgs = p;
                    if (!tuple.Item1.SentStartedEvent)
                    {
                        actualArgs = actualArgs.WithClientEvent(TorrentEvent.Started);
                    }

                    var peers = await tuple.Item2.AnnounceAsync(actualArgs);

                    LastAnnounceSucceeded = true;
                    AnnounceComplete?.InvokeAsync(this, new AnnounceResponseEventArgs(tuple.Item2, true, peers.AsReadOnly()));
                    return;
                } catch {
                }
            }

            LastAnnounceSucceeded = false;
            AnnounceComplete?.InvokeAsync(this, new AnnounceResponseEventArgs(null, false));
        }
Beispiel #5
0
        async Task <long> ConnectAsync()
        {
            var message = new ConnectMessage();

            // Reset the timer so we don't do two concurrent connect requests. It's just an optimisation
            // as concurrent requests are fine!
            LastConnected.Restart();

            // Send our request, which could take a few retries.
            var response = (ConnectResponseMessage) await SendAndReceiveAsync(message);

            // Reset the timer after we receive the response so we get maximum benefit from our
            // 2 minute allowance to use the connection id.
            LastConnected.Restart();
            return(response.ConnectionId);
        }
            public TimeSpan MeasureQueueDelay()
            {
                bool     shouldSchedule;
                TimeSpan delay;

                lock (_lockObj)
                {
                    var currentQueueDelay = _queueDelay.Elapsed;
                    delay = currentQueueDelay > _lastQueueDelay ? currentQueueDelay : _lastQueueDelay;

                    if (!_scheduled)
                    {
                        _scheduled     = true;
                        shouldSchedule = true;
                        _queueDelay.Restart();
                    }
                    else
                    {
                        shouldSchedule = false;
                    }
                }

                if (shouldSchedule)
                {
                    _ = ThreadPool.UnsafeQueueUserWorkItem(Callback, this);
                }

                return(delay);
            }
Beispiel #7
0
        public async Task <List <Peer> > AnnounceAsync(AnnounceParameters parameters)
        {
            var result = await DoAnnounceAsync(parameters);

            LastAnnounced.Restart();
            return(result);
        }
Beispiel #8
0
 /// <summary>
 /// Called when this silo receives a health probe request.
 /// </summary>
 public void OnReceivedProbeRequest()
 {
     lock (_lock)
     {
         _probeRequestStopwatch.Restart();
     }
 }
Beispiel #9
0
 public async ReusableTask <AnnounceResponse> AnnounceAsync(AnnounceParameters parameters, CancellationToken token)
 {
     try {
         return(await DoAnnounceAsync(parameters, token));
     } finally {
         LastAnnounced.Restart();
     }
 }
Beispiel #10
0
 internal void DhtAnnounce()
 {
     if (CanUseDht && (!LastDhtAnnounceTimer.IsRunning || LastDhtAnnounceTimer.Elapsed > MonoTorrent.Dht.DhtEngine.MinimumAnnounceInterval))
     {
         LastDhtAnnounce = DateTime.UtcNow;
         LastDhtAnnounceTimer.Restart();
         Engine?.DhtEngine.GetPeers(InfoHash);
     }
 }
Beispiel #11
0
        public async Task LocalPeerAnnounceAsync()
        {
            await ClientEngine.MainLoop;

            if (CanUseLocalPeerDiscovery && (!LastLocalPeerAnnounceTimer.IsRunning || LastLocalPeerAnnounceTimer.Elapsed > LocalPeerDiscovery.MinimumAnnounceInternal))
            {
                LastLocalPeerAnnounce = DateTime.Now;
                LastLocalPeerAnnounceTimer.Restart();
                await Engine?.LocalPeerDiscovery.Announce(InfoHash);
            }
        }
Beispiel #12
0
        ReusableTask Tick(int delta, bool waitForBufferedIO)
        {
            UpdateTimer.Restart();

            ReadMonitor.Tick(delta);
            WriteMonitor.Tick(delta);

            WriteLimiter.UpdateChunks(Settings.MaximumDiskWriteRate, WriteRate);
            ReadLimiter.UpdateChunks(Settings.MaximumDiskReadRate, ReadRate);

            var processTask = ProcessBufferedIOAsync();

            return(waitForBufferedIO ? processTask : ReusableTask.CompletedTask);
        }
Beispiel #13
0
        /// <summary>
        /// Should be called by ChokeUnchokeManager.ExecuteReview
        /// Logic taken from BitTyrant implementation
        /// </summary>
        internal void UpdateTyrantStats()
        {
            // if we're still being choked, set the time of our last choking
            if (IsChoking)
            {
                RoundsChoked++;

                LastChokedTime.Restart();
            }
            else
            {
                RoundsUnchoked++;

                if (AmInterested)
                {
                    //if we are interested and unchoked, update last measured download rate, unless it is 0
                    if (Monitor.DownloadSpeed > 0)
                    {
                        lastMeasuredDownloadRate = Monitor.DownloadSpeed;

                        maxObservedDownloadSpeed = Math.Max(lastMeasuredDownloadRate, maxObservedDownloadSpeed);
                    }
                }
            }

            // last rate wasn't sufficient to achieve reciprocation
            if (!AmChoking && IsChoking && IsInterested) // only increase upload rate if he's interested, otherwise he won't request any pieces
            {
                UploadRateForRecip = (UploadRateForRecip * 12) / 10;
            }

            // we've been unchoked by this guy for a while....
            if (!IsChoking && !AmChoking &&
                LastChokedTime.Elapsed.TotalSeconds > 30 &&
                LastRateReductionTime.Elapsed.TotalSeconds > 30)                  // only do rate reduction every 30s
            {
                UploadRateForRecip = (UploadRateForRecip * 9) / 10;
                LastRateReductionTime.Restart();
            }
        }
Beispiel #14
0
 internal void Seen(TimeSpan delta)
 {
     FailedCount   = 0;
     LastSeenDelta = delta;
     LastSeenTimer.Restart();
 }
Beispiel #15
0
 internal void Changed(TimeSpan delta)
 {
     LastChangedDelta = delta;
     LastChangedTimer.Restart();
 }