예제 #1
0
func (tkr *Tracker) updatePeer(ann *models.Announce, peer *models.Peer) (created bool, err error) {
	p, t := ann.Peer, ann.Torrent

	switch {
	case t.Seeders.Contains(p.Key()):
		err = tkr.PutSeeder(t.Infohash, p)
		if err != nil {
			return
		}

	case t.Leechers.Contains(p.Key()):
		err = tkr.PutLeecher(t.Infohash, p)
		if err != nil {
			return
		}

	default:
		if ann.Left == 0 {
			err = tkr.PutSeeder(t.Infohash, p)
			if err != nil {
				return
			}
			stats.RecordPeerEvent(stats.NewSeed)

		} else {
			err = tkr.PutLeecher(t.Infohash, p)
			if err != nil {
				return
			}
			stats.RecordPeerEvent(stats.NewLeech)
		}
		created = true
	}
	return
}
예제 #2
0
// Purge iterates over all of the peers within a PeerMap and deletes them if
// they are older than the provided time.
func (pm *PeerMap) Purge(unixtime int64) {
	pm.Lock()
	defer pm.Unlock()
	for key, peer := range pm.Peers {
		if peer.LastAnnounce <= unixtime {
			delete(pm.Peers, key)
			if pm.Seeders {
				stats.RecordPeerEvent(stats.ReapedSeed)
			} else {
				stats.RecordPeerEvent(stats.ReapedLeech)
			}
		}
	}
}
예제 #3
0
// leecherFinished moves a peer from the leeching pool to the seeder pool.
func (tkr *Tracker) leecherFinished(t *models.Torrent, p *models.Peer) error {
	if err := tkr.DeleteLeecher(t.Infohash, p); err != nil {
		return err
	}

	if err := tkr.PutSeeder(t.Infohash, p); err != nil {
		return err
	}

	stats.RecordPeerEvent(stats.Completed)
	return nil
}
예제 #4
0
func (tkr *Tracker) handlePeerEvent(ann *models.Announce, p *models.Peer) (snatched bool, err error) {
	p, t := ann.Peer, ann.Torrent

	switch {
	case ann.Event == "stopped" || ann.Event == "paused":
		// updateSwarm checks if the peer is active on the torrent,
		// so one of these branches must be followed.
		if t.Seeders.Contains(p.Key()) {
			err = tkr.DeleteSeeder(t.Infohash, p)
			if err != nil {
				return
			}
			stats.RecordPeerEvent(stats.DeletedSeed)

		} else if t.Leechers.Contains(p.Key()) {
			err = tkr.DeleteLeecher(t.Infohash, p)
			if err != nil {
				return
			}
			stats.RecordPeerEvent(stats.DeletedLeech)
		}

	case t.Leechers.Contains(p.Key()) && (ann.Event == "completed" || ann.Left == 0):
		// A leecher has completed or this is the first time we've seen them since
		// they've completed.
		err = tkr.leecherFinished(t, p)
		if err != nil {
			return
		}

		// Only mark as snatched if we receive the completed event.
		if ann.Event == "completed" {
			snatched = true
		}
	}

	return
}