예제 #1
0
파일: announce.go 프로젝트: dtrackd/chihaya
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, p.HasIPv6())

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

	case ann.Event == "completed":
		tkr.leecherFinished(t, p)
		snatched = true

	case t.Leechers.Contains(p.Key()) && ann.Left == 0:
		// A leecher completed but the event was never received.
		err = tkr.leecherFinished(t, p)
	}

	return
}
예제 #2
0
파일: announce.go 프로젝트: dtrackd/chihaya
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, p.HasIPv6())

		} else {
			err = tkr.PutLeecher(t.Infohash, p)
			if err != nil {
				return
			}
			stats.RecordPeerEvent(stats.NewLeech, p.HasIPv6())
		}
		created = true
	}
	return
}
예제 #3
0
파일: peermap.go 프로젝트: ypie/chihaya
// 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 _, subnetmap := range pm.Peers {
		for key, peer := range subnetmap {
			if peer.LastAnnounce <= unixtime {
				atomic.AddInt32(&(pm.Size), -1)
				delete(subnetmap, key)
				if pm.Seeders {
					stats.RecordPeerEvent(stats.ReapedSeed, peer.HasIPv6())
				} else {
					stats.RecordPeerEvent(stats.ReapedLeech, peer.HasIPv6())
				}
			}
		}
	}
}
예제 #4
0
파일: announce.go 프로젝트: ypie/chihaya
// 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, p.HasIPv6())
	return nil
}
예제 #5
0
파일: announce.go 프로젝트: ypie/chihaya
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, p.HasIPv6())

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

	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
}