Ignore:
Timestamp:
Oct 13, 2007, 1:54:05 PM (15 years ago)
Author:
charles
Message:

merge in the parts of peerutils' peer pruning code that still make sense

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r3362 r3393  
    5555    SNUBBED_SEC = 60,
    5656
    57     /* this is arbitrary and, hopefully, temporary until we come up
    58      * with a better idea for managing the connection limits */
     57    /* arbitrary */
    5958    MAX_CONNECTED_PEERS_PER_TORRENT = 60,
     59
     60    /* when many peers are available, keep idle ones this long */
     61    MIN_UPLOAD_IDLE_SECS = 60,
     62
     63    /* when few peers are available, keep idle ones this long */
     64    MAX_UPLOAD_IDLE_SECS = 240,
    6065
    6166    /* how many peers to unchoke per-torrent. */
     
    14801485/***
    14811486****
    1482 ****
     1487****  Life and Death
    14831488****
    14841489***/
    14851490
    1486 #define LAISSEZ_FAIRE_PERIOD_SECS 90
     1491static int
     1492shouldPeerBeClosed( const Torrent * t, const tr_peer * peer, int peerCount )
     1493{
     1494    const tr_torrent * tor = t->tor;
     1495    const time_t now = time( NULL );
     1496    const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
     1497
     1498    /* if it's marked for purging, close it */
     1499    if( peer->doPurge ) {
     1500        tordbg( t, "purging peer %p because its doPurge flag is set", tr_peerIoAddrStr(&atom->addr,atom->port) );
     1501        return TRUE;
     1502    }
     1503
     1504    /* if we're both seeds and it's been long enough for a pex exchange, close it */
     1505    if( 1 ) {
     1506        const int clientIsSeed = tr_cpGetStatus( tor->completion ) != TR_CP_INCOMPLETE;
     1507        const int peerIsSeed = atom->flags & ADDED_F_SEED_FLAG;
     1508        if( peerIsSeed && clientIsSeed && ( tor->pexDisabled || (now-atom->time>=30) ) ) {
     1509            tordbg( t, "purging peer %p because we're both seeds", tr_peerIoAddrStr(&atom->addr,atom->port) );
     1510            return TRUE;
     1511        }
     1512    }
     1513
     1514    /* disconnect if it's been too long since piece data has been transferred.
     1515     * this is on a sliding scale based on number of available peers... */
     1516    if( 1 ) {
     1517        const int relaxStrictnessIfFewerThanN = (int)((MAX_CONNECTED_PEERS_PER_TORRENT * 0.9) + 0.5);
     1518        /* if we have >= relaxIfFewerThan, strictness is 100%.
     1519         * if we have zero connections, strictness is 0% */
     1520        const double strictness = peerCount >= relaxStrictnessIfFewerThanN
     1521            ? 1.0
     1522            : peerCount / (double)relaxStrictnessIfFewerThanN;
     1523        const int lo = MIN_UPLOAD_IDLE_SECS;
     1524        const int hi = MAX_UPLOAD_IDLE_SECS;
     1525        const int limit = lo + ((hi-lo) * strictness);
     1526        const time_t then = peer->pieceDataActivityDate;
     1527        const int idleTime = then ? (now-then) : 0;
     1528        if( idleTime > limit ) {
     1529            tordbg( t, "purging peer %p it's been %d secs since we shared anything",
     1530                       tr_peerIoAddrStr(&atom->addr,atom->port), idleTime );
     1531            return TRUE;
     1532        }
     1533    }
     1534
     1535    return FALSE;
     1536}
    14871537
    14881538static tr_peer **
    1489 getWeakConnections( Torrent * t, int * setmeSize )
    1490 {
    1491     int i, insize, outsize;
    1492     tr_peer ** peers = (tr_peer**) tr_ptrArrayPeek( t->peers, &insize );
    1493     struct tr_peer ** ret = tr_new( tr_peer*, insize );
    1494     const int clientIsSeed = tr_cpGetStatus( t->tor->completion ) != TR_CP_INCOMPLETE;
    1495     const time_t now = time( NULL );
     1539getPeersToClose( Torrent * t, int * setmeSize )
     1540{
     1541    int i, peerCount, outsize;
     1542    tr_peer ** peers = (tr_peer**) tr_ptrArrayPeek( t->peers, &peerCount );
     1543    struct tr_peer ** ret = tr_new( tr_peer*, peerCount );
    14961544
    14971545    assert( torrentIsLocked( t ) );
    14981546
    1499     for( i=outsize=0; i<insize; ++i )
    1500     {
    1501         tr_peer * peer = peers[i];
    1502         int isWeak;
    1503         const struct peer_atom * atom = getExistingAtom( t, &peer->in_addr );
    1504         const int peerIsSeed = atom->flags & ADDED_F_SEED_FLAG;
    1505         const double throughput = getWeightedThroughput( peer );
    1506 
    1507         assert( atom != NULL );
    1508 
    1509         if( peer->doPurge ) {
    1510             tordbg( t, "purging peer %s because it's got doPurge flagged", tr_peerIoAddrStr(&atom->addr,atom->port) );
    1511             isWeak = TRUE;
    1512         } else if( throughput >= 3 ) {
    1513             tordbg( t, "keeping peer %s because it's got a good throughput", tr_peerIoAddrStr(&atom->addr,atom->port) );
    1514             isWeak = FALSE;
    1515         } else if( peerIsSeed && clientIsSeed ) {
    1516             tordbg( t, "%s peer is a seed and so are we", tr_peerIoAddrStr(&atom->addr,atom->port) );
    1517             isWeak = t->tor->pexDisabled || (now-atom->time>=30);
    1518         } else if( !atom->time || ( ( now - atom->time ) < LAISSEZ_FAIRE_PERIOD_SECS ) ) {
    1519             tordbg( t, "%s too new to purge", tr_peerIoAddrStr(&atom->addr,atom->port) );
    1520             isWeak = FALSE;
    1521         } else {
    1522             isWeak = ( now - peer->pieceDataActivityDate ) > 180;
    1523             tordbg( t, "%s peer %p", (isWeak?"purging":"keeping"), tr_peerIoAddrStr(&atom->addr,atom->port) );
    1524         }
    1525 
    1526         if( isWeak )
    1527             ret[outsize++] = peer;
    1528     }
     1547    for( i=outsize=0; i<peerCount; ++i )
     1548        if( shouldPeerBeClosed( t, peers[i], peerCount ) )
     1549            ret[outsize++] = peers[i];
    15291550
    15301551    *setmeSize = outsize;
     
    15821603
    15831604        /* if we used this peer recently, give someone else a turn */
    1584         if( ( now - atom->time ) < LAISSEZ_FAIRE_PERIOD_SECS ) {
     1605        if( ( now - atom->time ) < 60 ) {
    15851606            tordbg( t, "RECONNECT peer %d (%s) is in its grace period..",
    15861607                    i, tr_peerIoAddrStr(&atom->addr,atom->port) );
     
    16091630    else
    16101631    {
    1611         int i, nCandidates, nWeak, nAdd;
     1632        int i, nCandidates, nBad, nAdd;
    16121633        struct peer_atom ** candidates = getPeerCandidates( t, &nCandidates );
    1613         struct tr_peer ** connections = getWeakConnections( t, &nWeak );
     1634        struct tr_peer ** connections = getPeersToClose( t, &nBad );
    16141635        const int peerCount = tr_ptrArraySize( t->peers );
    16151636
    1616         if( nWeak || nCandidates )
    1617             tordbg( t, "reconnect pulse for [%s]: %d weak connections, "
     1637        if( nBad || nCandidates )
     1638            tordbg( t, "reconnect pulse for [%s]: %d bad connections, "
    16181639                       "%d connection candidates, %d atoms, max per pulse is %d",
    1619                        t->tor->info.name, nWeak, nCandidates,
     1640                       t->tor->info.name, nBad, nCandidates,
    16201641                       tr_ptrArraySize(t->pool),
    16211642                       (int)MAX_RECONNECTIONS_PER_PULSE );
    16221643
    16231644        /* disconnect some peers */
    1624         for( i=0; i<nWeak; ++i )
     1645        for( i=0; i<nBad; ++i )
    16251646            removePeer( t, connections[i] );
    16261647
Note: See TracChangeset for help on using the changeset viewer.