Only close websocket when it's not participating in any more swarms

This commit is contained in:
Feross Aboukhadijeh 2017-02-02 20:51:07 -08:00
parent 29d4564bbd
commit d534582a8c
2 changed files with 25 additions and 5 deletions

View File

@ -7,19 +7,29 @@ var randomIterate = require('random-iterate')
// Regard this as the default implementation of an interface that you
// need to support when overriding Server.createSwarm() and Server.getSwarm()
function Swarm (infoHash, server) {
this.infoHash = infoHash
this.complete = 0
this.incomplete = 0
this.peers = new LRU({
max: server.peersCacheLength || 1000,
maxAge: server.peersCacheTtl || 20 * 60 * 1000 // 20 minutes
})
// When a websocket peer is evicted from the LRU cache, close the websocket
// after a short timeout period. We wait 1s so the server has a chance to send
// a response to 'stopped' events, which remove the peer and cause an eviction.
// When a peer is evicted from the LRU store, send a synthetic 'stopped' event
// so the stats get updated correctly.
this.peers.on('evict', function (data) {
var peer = data.value
if (peer.socket) {
this.announce({
type: peer.type,
event: 'stopped',
numwant: 0,
peer_id: peer.peerId
}, noop)
// When a websocket peer is evicted, and it's not in any other swarms, close
// the websocket to conserve server resources.
if (peer.socket && peer.socket.infoHashes.length === 0) {
try {
peer.socket.close()
peer.socket = null
@ -86,6 +96,14 @@ Swarm.prototype._onAnnounceStopped = function (params, peer, id) {
if (peer.complete) this.complete -= 1
else this.incomplete -= 1
// If it's a websocket, remove this swarm's infohash from the list of active
// swarms that this peer is participating in.
if (peer.socket) {
var index = peer.socket.infoHashes.indexOf(this.infoHash)
peer.socket.infoHashes.splice(index, 1)
}
this.peers.remove(id)
}
@ -133,3 +151,5 @@ Swarm.prototype._getPeers = function (numwant, ownPeerId, isWebRTC) {
}
return peers
}
function noop () {}

View File

@ -585,7 +585,7 @@ Server.prototype._onWebSocketClose = function (socket) {
debug('websocket close %s', socket.peerId)
if (socket.peerId) {
socket.infoHashes.forEach(function (infoHash) {
socket.infoHashes.slice(0).forEach(function (infoHash) {
var swarm = self.torrents[infoHash]
if (swarm) {
swarm.announce({