(trunk libT) #3329 "connection problems when downloading" -- apply Longinus00's fixSlowStart.diff
This commit is contained in:
parent
f3ab57e082
commit
91cc3f4a2d
|
@ -193,6 +193,8 @@ typedef struct tr_torrent_peers
|
||||||
int pieceCount;
|
int pieceCount;
|
||||||
|
|
||||||
int interestedCount;
|
int interestedCount;
|
||||||
|
int maxPeers;
|
||||||
|
tr_recentHistory * noBlocksCancelsCount;
|
||||||
|
|
||||||
/* An arbitrary metric of how congested the downloads are.
|
/* An arbitrary metric of how congested the downloads are.
|
||||||
* Based on how many of requests are cancelled and how many are completed.
|
* Based on how many of requests are cancelled and how many are completed.
|
||||||
|
@ -450,6 +452,7 @@ torrentDestructor( void * vt )
|
||||||
tr_ptrArrayDestruct( &t->pool, (PtrArrayForeachFunc)tr_free );
|
tr_ptrArrayDestruct( &t->pool, (PtrArrayForeachFunc)tr_free );
|
||||||
tr_ptrArrayDestruct( &t->outgoingHandshakes, NULL );
|
tr_ptrArrayDestruct( &t->outgoingHandshakes, NULL );
|
||||||
tr_ptrArrayDestruct( &t->peers, NULL );
|
tr_ptrArrayDestruct( &t->peers, NULL );
|
||||||
|
tr_historyFree( t->noBlocksCancelsCount );
|
||||||
|
|
||||||
tr_free( t->requests );
|
tr_free( t->requests );
|
||||||
tr_free( t->pieces );
|
tr_free( t->pieces );
|
||||||
|
@ -472,6 +475,7 @@ torrentConstructor( tr_peerMgr * manager,
|
||||||
t->peers = TR_PTR_ARRAY_INIT;
|
t->peers = TR_PTR_ARRAY_INIT;
|
||||||
t->webseeds = TR_PTR_ARRAY_INIT;
|
t->webseeds = TR_PTR_ARRAY_INIT;
|
||||||
t->outgoingHandshakes = TR_PTR_ARRAY_INIT;
|
t->outgoingHandshakes = TR_PTR_ARRAY_INIT;
|
||||||
|
t->noBlocksCancelsCount = tr_historyNew( CANCEL_HISTORY_SEC, 1 );
|
||||||
|
|
||||||
for( i = 0; i < tor->info.webseedCount; ++i )
|
for( i = 0; i < tor->info.webseedCount; ++i )
|
||||||
{
|
{
|
||||||
|
@ -2486,36 +2490,58 @@ rechokeDownloads( Torrent * t )
|
||||||
cancels += c;
|
cancels += c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !t->interestedCount )
|
if( !t->maxPeers )
|
||||||
{
|
{
|
||||||
/* this is the torrent's first time to call this function...
|
/* this is the torrent's first time to call this function...
|
||||||
* start off optimistically by allowing interest in many peers */
|
* start off optimistically by allowing interest in many peers */
|
||||||
maxPeers = t->tor->maxConnectedPeers;
|
maxPeers = t->tor->maxConnectedPeers;
|
||||||
}
|
}
|
||||||
else if( !blocks )
|
else if( !blocks && cancels )
|
||||||
{
|
{
|
||||||
/* we've gotten cancels but zero blocks...
|
/* we've gotten cancels but zero blocks...
|
||||||
* something is seriously wrong. throttle back sharply */
|
* something is seriously wrong. throttle back sharply */
|
||||||
maxPeers = t->interestedCount * 0.5;
|
maxPeers = t->interestedCount * 0.5;
|
||||||
}
|
}
|
||||||
else
|
else if( blocks )
|
||||||
{
|
{
|
||||||
const double cancelRate = cancels / (double)(cancels + blocks);
|
const double cancelRate = cancels / (double)(cancels + blocks );
|
||||||
|
|
||||||
|
/* if we're getting cancels then use interestedCount instead of
|
||||||
|
* maxPeers to scale faster */
|
||||||
if( cancelRate >= 0.20 ) maxPeers = t->interestedCount * 0.7;
|
if( cancelRate >= 0.20 ) maxPeers = t->interestedCount * 0.7;
|
||||||
else if( cancelRate >= 0.10 ) maxPeers = t->interestedCount * 0.8;
|
else if( cancelRate >= 0.10 ) maxPeers = t->interestedCount * 0.8;
|
||||||
else if( cancelRate >= 0.05 ) maxPeers = t->interestedCount * 0.9;
|
else if( cancelRate >= 0.05 ) maxPeers = t->interestedCount * 0.9;
|
||||||
else if( cancelRate >= 0.01 ) maxPeers = t->interestedCount;
|
else if( cancelRate >= 0.01 ) maxPeers = t->interestedCount;
|
||||||
else maxPeers = t->interestedCount + 1;
|
else maxPeers = t->maxPeers + 1;
|
||||||
|
|
||||||
/* if things are getting worse, don't add more peers */
|
/* if things are getting worse, don't add more peers */
|
||||||
if( ( t->cancelRate > 0.01 ) && ( cancelRate > t->cancelRate ) )
|
if( ( t->cancelRate > 0.01 ) && ( cancelRate > t->cancelRate ) )
|
||||||
maxPeers = MIN( maxPeers, t->interestedCount );
|
maxPeers = MIN( maxPeers, t->maxPeers );
|
||||||
|
|
||||||
t->cancelRate = cancelRate;
|
t->cancelRate = cancelRate;
|
||||||
|
|
||||||
tordbg( t, "cancel rate is %.3f -- changing the "
|
tordbg( t, "cancel rate is %.3f -- changing the "
|
||||||
"number of peers we're interested in from %d to %d",
|
"number of peers we're interested in from %d to %d",
|
||||||
cancelRate, t->interestedCount, maxPeers );
|
cancelRate, t->maxPeers, maxPeers );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const unsigned maxCount = 10; /* maximum times in this block in the past two minutes */
|
||||||
|
tr_historyAdd( t->noBlocksCancelsCount, now, 1 );
|
||||||
|
if( tr_historyGet( t->noBlocksCancelsCount, now, msec * 2 ) < maxCount )
|
||||||
|
{
|
||||||
|
/* no blocks and no cancels means either that the torrent
|
||||||
|
* just started or peers are unresponsive/nonexistent,
|
||||||
|
* either way there's nothing to do */
|
||||||
|
maxPeers = t->maxPeers;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* we've been in here for a while so maybe the network is down or there are no
|
||||||
|
* good peers. maximize the chance of connecting to a good peer
|
||||||
|
* if/when they show up */
|
||||||
|
maxPeers = t->tor->maxConnectedPeers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2525,6 +2551,8 @@ rechokeDownloads( Torrent * t )
|
||||||
if( maxPeers > t->tor->maxConnectedPeers )
|
if( maxPeers > t->tor->maxConnectedPeers )
|
||||||
maxPeers = t->tor->maxConnectedPeers;
|
maxPeers = t->tor->maxConnectedPeers;
|
||||||
|
|
||||||
|
t->maxPeers = maxPeers;
|
||||||
|
|
||||||
/* separate the peers into "good" (ones with a low cancel-to-block ratio),
|
/* separate the peers into "good" (ones with a low cancel-to-block ratio),
|
||||||
* untested peers, and "bad" (ones with a high cancel-to-block ratio).
|
* untested peers, and "bad" (ones with a high cancel-to-block ratio).
|
||||||
* That's the order in which we'll choose who to show interest in */
|
* That's the order in which we'll choose who to show interest in */
|
||||||
|
|
Loading…
Reference in New Issue