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 // Regard this as the default implementation of an interface that you
// need to support when overriding Server.createSwarm() and Server.getSwarm() // need to support when overriding Server.createSwarm() and Server.getSwarm()
function Swarm (infoHash, server) { function Swarm (infoHash, server) {
this.infoHash = infoHash
this.complete = 0 this.complete = 0
this.incomplete = 0 this.incomplete = 0
this.peers = new LRU({ this.peers = new LRU({
max: server.peersCacheLength || 1000, max: server.peersCacheLength || 1000,
maxAge: server.peersCacheTtl || 20 * 60 * 1000 // 20 minutes maxAge: server.peersCacheTtl || 20 * 60 * 1000 // 20 minutes
}) })
// When a websocket peer is evicted from the LRU cache, close the websocket // When a peer is evicted from the LRU store, send a synthetic 'stopped' event
// after a short timeout period. We wait 1s so the server has a chance to send // so the stats get updated correctly.
// a response to 'stopped' events, which remove the peer and cause an eviction.
this.peers.on('evict', function (data) { this.peers.on('evict', function (data) {
var peer = data.value 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 { try {
peer.socket.close() peer.socket.close()
peer.socket = null peer.socket = null
@ -86,6 +96,14 @@ Swarm.prototype._onAnnounceStopped = function (params, peer, id) {
if (peer.complete) this.complete -= 1 if (peer.complete) this.complete -= 1
else this.incomplete -= 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) this.peers.remove(id)
} }
@ -133,3 +151,5 @@ Swarm.prototype._getPeers = function (numwant, ownPeerId, isWebRTC) {
} }
return peers return peers
} }
function noop () {}

View File

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