1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 09:37:56 +00:00

(trunk libT) #3600 "Improve rechokeDownloads' peer limiter" -- fixed with patch from Longinus00

This commit is contained in:
Charles Kerr 2010-12-04 17:17:44 +00:00
parent d684d6398b
commit aa79cbcbf2

View file

@ -202,12 +202,7 @@ typedef struct tr_torrent_peers
int interestedCount; int interestedCount;
int maxPeers; int maxPeers;
tr_recentHistory * noBlocksCancelsCount; time_t lastCancel;
/* An arbitrary metric of how congested the downloads are.
* Based on how many of requests are cancelled and how many are completed.
* Lower values indicate less congestion. */
double cancelRate;
} }
Torrent; Torrent;
@ -460,7 +455,6 @@ 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 );
@ -483,7 +477,6 @@ 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( NO_BLOCKS_CANCEL_HISTORY, ( RECHOKE_PERIOD_MSEC / 1000 ) );
for( i = 0; i < tor->info.webseedCount; ++i ) for( i = 0; i < tor->info.webseedCount; ++i )
{ {
@ -2072,6 +2065,7 @@ tr_peerMgrStartTorrent( tr_torrent * tor )
ensureMgrTimersExist( t->manager ); ensureMgrTimersExist( t->manager );
t->isRunning = TRUE; t->isRunning = TRUE;
t->maxPeers = t->tor->maxConnectedPeers;
rechokePulse( 0, 0, t->manager ); rechokePulse( 0, 0, t->manager );
managerUnlock( t->manager ); managerUnlock( t->manager );
@ -2463,6 +2457,7 @@ rechokeDownloads( Torrent * t )
{ {
int blocks = 0; int blocks = 0;
int cancels = 0; int cancels = 0;
time_t timeSinceCancel;
/* Count up how many blocks & cancels each peer has. /* Count up how many blocks & cancels each peer has.
* *
@ -2491,62 +2486,34 @@ rechokeDownloads( Torrent * t )
cancels += c; cancels += c;
} }
if( !t->maxPeers ) if( cancels > 0 )
{ {
/* this is the torrent's first time to call this function... /* cancelRate: of the block requests we've recently made, the percentage we cancelled.
* start off optimistically by allowing interest in many peers */ * higher values indicate more congestion. */
maxPeers = t->tor->maxConnectedPeers; const double cancelRate = cancels / (double)(cancels + blocks);
const double mult = 1 - MIN( cancelRate, 0.5 );
maxPeers = t->interestedCount * mult;
tordbg( t, "cancel rate is %.3f -- reducing the "
"number of peers we're interested in by %.0f percent",
cancelRate, mult * 100 );
t->lastCancel = now;
} }
else if( !blocks && cancels )
{
/* we've gotten cancels but zero blocks...
* something is seriously wrong. throttle back sharply */
maxPeers = t->interestedCount * 0.5;
}
else if( blocks )
{
const double cancelRate = cancels / (double)(cancels + blocks );
/* if we're getting cancels then use interestedCount instead of timeSinceCancel = now - t->lastCancel;
* maxPeers to scale faster */ if( timeSinceCancel )
if( cancelRate >= 0.20 ) maxPeers = t->interestedCount * 0.7;
else if( cancelRate >= 0.10 ) maxPeers = t->interestedCount * 0.8;
else if( cancelRate >= 0.05 ) maxPeers = t->interestedCount * 0.9;
else if( cancelRate >= 0.01 ) maxPeers = t->interestedCount;
else maxPeers = t->maxPeers + 1;
/* if things are getting worse, don't add more peers */
if( ( t->cancelRate > 0.01 ) && ( cancelRate > t->cancelRate ) )
maxPeers = MIN( maxPeers, t->maxPeers );
t->cancelRate = cancelRate;
tordbg( t, "cancel rate is %.3f -- changing the "
"number of peers we're interested in from %d to %d",
cancelRate, t->maxPeers, maxPeers );
}
else
{ {
const unsigned maxCount = 10; /* maximum times in this block in the past two minutes */ const int maxIncrease = 15;
tr_historyAdd( t->noBlocksCancelsCount, now, 1 ); const time_t maxHistory = 2 * CANCEL_HISTORY_SEC;
if( tr_historyGet( t->noBlocksCancelsCount, now, NO_BLOCKS_CANCEL_HISTORY ) < maxCount ) const double mult = MIN( timeSinceCancel, maxHistory ) / (double) maxHistory;
{ const int inc = maxIncrease * mult;
/* no blocks and no cancels means either that the torrent maxPeers = t->maxPeers + inc;
* just started or peers are unresponsive/nonexistent, tordbg( t, "time since last cancel is %li -- increasing the "
* either way there's nothing to do */ "number of peers we're interested in by %d",
maxPeers = t->maxPeers; timeSinceCancel, inc );
}
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;
}
} }
} }
/* don't let the previous paragraph's number tweaking go too far... */ /* don't let the previous section's number tweaking go too far... */
if( maxPeers < MIN_INTERESTING_PEERS ) if( maxPeers < MIN_INTERESTING_PEERS )
maxPeers = MIN_INTERESTING_PEERS; maxPeers = MIN_INTERESTING_PEERS;
if( maxPeers > t->tor->maxConnectedPeers ) if( maxPeers > t->tor->maxConnectedPeers )