11module . exports = Swarm
22
33var debug = require ( 'debug' ) ( 'bittorrent-tracker' )
4+ var LRU = require ( 'lru' )
45var randomIterate = require ( 'random-iterate' )
56
67// Regard this as the default implementation of an interface that you
78// need to support when overriding Server.createSwarm() and Server.getSwarm()
89function Swarm ( infoHash , server ) {
9- this . peers = { }
10+ this . peers = new LRU ( {
11+ max : server . peersCacheLength || 10000 ,
12+ maxAge : server . peersCacheTtl || 900 // 900s = 15 minutes
13+ } )
1014 this . complete = 0
1115 this . incomplete = 0
1216}
1317
1418Swarm . prototype . announce = function ( params , cb ) {
1519 var self = this
1620 var id = params . type === 'ws' ? params . peer_id : params . addr
17- var peer = self . peers [ id ]
21+ // Mark the source peer as recently used in cache
22+ var peer = self . peers . get ( id )
1823
1924 if ( params . event === 'started' ) {
2025 self . _onAnnounceStarted ( params , peer )
@@ -51,14 +56,14 @@ Swarm.prototype._onAnnounceStarted = function (params, peer) {
5156 if ( params . left === 0 ) this . complete += 1
5257 else this . incomplete += 1
5358 var id = params . type === 'ws' ? params . peer_id : params . addr
54- peer = this . peers [ id ] = {
59+ peer = this . peers . set ( id , {
5560 type : params . type ,
5661 complete : params . left === 0 ,
5762 peerId : params . peer_id , // as hex
5863 ip : params . ip ,
5964 port : params . port ,
6065 socket : params . socket // only websocket
61- }
66+ } )
6267}
6368
6469Swarm . prototype . _onAnnounceStopped = function ( params , peer ) {
@@ -70,7 +75,7 @@ Swarm.prototype._onAnnounceStopped = function (params, peer) {
7075 if ( peer . complete ) this . complete -= 1
7176 else this . incomplete -= 1
7277 var id = params . type === 'ws' ? params . peer_id : params . addr
73- delete this . peers [ id ]
78+ this . peers . remove ( id )
7479}
7580
7681Swarm . prototype . _onAnnounceCompleted = function ( params , peer ) {
@@ -103,10 +108,11 @@ Swarm.prototype._onAnnounceUpdate = function (params, peer) {
103108
104109Swarm . prototype . _getPeers = function ( numwant , ownPeerId , isWebRTC ) {
105110 var peers = [ ]
106- var ite = randomIterate ( Object . keys ( this . peers ) )
111+ var ite = randomIterate ( Object . keys ( this . peers . cache ) )
107112 var peerId
108113 while ( ( peerId = ite ( ) ) && peers . length < numwant ) {
109- var peer = this . peers [ peerId ]
114+ // Don't mark the peer as most recently used on announce
115+ var peer = this . peers . peek ( peerId )
110116 if ( isWebRTC && peer . peerId === ownPeerId ) continue // don't send peer to itself
111117 if ( ( isWebRTC && peer . type !== 'ws' ) || ( ! isWebRTC && peer . type === 'ws' ) ) continue // send proper peer type
112118 peers . push ( peer )
0 commit comments