<commit_before>module.exports = Swarm

var arrayRemove = require('unordered-array-remove')
var debug = require('debug')('bittorrent-tracker:swarm')
var LRU = require('lru')
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) {
  var self = this
  self.infoHash = infoHash
  self.complete = 0
  self.incomplete = 0

  self.peers = new LRU({
    max: server.peersCacheLength || 1000,
    maxAge: server.peersCacheTtl || 20 * 60 * 1000 // 20 minutes
  })

  // When a peer is evicted from the LRU store, send a synthetic 'stopped' event
  // so the stats get updated correctly.
  self.peers.on('evict', function (data) {
    var peer = data.value
    var params = {
      type: peer.type,
      event: 'stopped',
      numwant: 0,
      peer_id: peer.peerId
    }
    self._onAnnounceStopped(params, peer, peer.peerId)

    // 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
      } catch (err) {}
    }
  })
}

Swarm.prototype.announce = function (params, cb) {
  var self = this
  var id = params.type === 'ws' ? params.peer_id : params.addr
  // Mark the source peer as recently used in cache
  var peer = self.peers.get(id)

  if (params.event === 'started') {
    self._onAnnounceStarted(params, peer, id)
  } else if (params.event === 'stopped') {
    self._onAnnounceStopped(params, peer, id)
  } else if (params.event === 'completed') {
    self._onAnnounceCompleted(params, peer, id)
  } else if (params.event === 'update') {
    self._onAnnounceUpdate(params, peer, id)
  } else {
    cb(new Error('invalid event'))
    return
  }
  cb(null, {
    complete: self.complete,
    incomplete: self.incomplete,
    peers: self._getPeers(params.numwant, params.peer_id, !!params.socket)<commit_msg>do not close socket even when it's not in other swarms<commit_after>module.exports = Swarm

var arrayRemove = require('unordered-array-remove')
var debug = require('debug')('bittorrent-tracker:swarm')
var LRU = require('lru')
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) {
  var self = this
  self.infoHash = infoHash
  self.complete = 0
  self.incomplete = 0

  self.peers = new LRU({
    max: server.peersCacheLength || 1000,
    maxAge: server.peersCacheTtl || 20 * 60 * 1000 // 20 minutes
  })

  // When a peer is evicted from the LRU store, send a synthetic 'stopped' event
  // so the stats get updated correctly.
  self.peers.on('evict', function (data) {
    var peer = data.value
    var params = {
      type: peer.type,
      event: 'stopped',
      numwant: 0,
      peer_id: peer.peerId
    }
    self._onAnnounceStopped(params, peer, peer.peerId)
    peer.socket = null
  })
}

Swarm.prototype.announce = function (params, cb) {
  var self = this
  var id = params.type === 'ws' ? params.peer_id : params.addr
  // Mark the source peer as recently used in cache
  var peer = self.peers.get(id)

  if (params.event === 'started') {
    self._onAnnounceStarted(params, peer, id)
  } else if (params.event === 'stopped') {
    self._onAnnounceStopped(params, peer, id)
  } else if (params.event === 'completed') {
    self._onAnnounceCompleted(params, peer, id)
  } else if (params.event === 'update') {
    self._onAnnounceUpdate(params, peer, id)
  } else {
    cb(new Error('invalid event'))
    return
  }
  cb(null, {
    complete: self.complete,
    incomplete: self.incomplete,
    peers: self._getPeers(params.numwant, params.peer_id, !!params.socket)
{'fraction_non_alphanumeric': 0.12598425196850394, 'fraction_numerical': 0.00889001778003556, 'mean_word_length': 3.289760348583878, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5068424', 'n_tokens_mistral': 1326, 'n_tokens_neox': 1264, 'n_words': 369}