Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/webtorrent/webtorrent.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeross Aboukhadijeh <feross@feross.org>2016-04-21 11:10:30 +0300
committerFeross Aboukhadijeh <feross@feross.org>2016-04-21 11:10:30 +0300
commit63e4aee7bd016f258d81708af9c03cf608968816 (patch)
tree9b28e5e486c8a0bcd53d18a1eed2eb57a879f2b0 /lib/torrent.js
parenta47d2ce4b27896a4c2e2e3820f69c712c2a0de3e (diff)
More thorough object cleanup
- Only pass `torrent.infoHash` to the Chunk Store constructor, instead of the `Torrent` instance itself, to prevent accidental memory leaks of the `Torrent` object by the store. (Open an issue if you were using other properties. They can be re-added.) - Non-fatal errors with a single torrent will be emitted at `torrent.on('error')`. You should listen to this event. Previously, all torrent errors were also emitted on `client.on('error')` and handling `torrent.on('error')` was optional. This design is better since now it is possible to distinguish between fatal client errors (`client.on('error')`) when the whole client becomes unusable versus recoverable errors where only a single torrent fails (`torrent.on('error')`) but the client can continue to be used. However, if there is no `torrent.on('error')` event, then the error will be forwarded to `client.on('error')`. This prevents crashing the client when the user only has a listener on the client, but it makes it impossible for them to determine a client error versus a torrent error. - Errors creating a torrent with `client.seed` are now emitted on the returned `torrent` object instead of the client (unless there is no event listeners on `torrent.on('error')` as previously discussed). The torrent object is now also destroyed automatically for the user, as was probably expected. - If `client.get` is passed a `Torrent` instance, it now only returns it if it is present in the client.
Diffstat (limited to 'lib/torrent.js')
-rw-r--r--lib/torrent.js33
1 files changed, 27 insertions, 6 deletions
diff --git a/lib/torrent.js b/lib/torrent.js
index fc5f495..296f579 100644
--- a/lib/torrent.js
+++ b/lib/torrent.js
@@ -92,10 +92,10 @@ function Torrent (torrentId, client, opts) {
this.metadata = null
this.store = null
- this.files = null
+ this.files = []
+ this.pieces = []
this._amInterested = false
- this.pieces = []
this._selections = []
this._critical = []
@@ -253,6 +253,7 @@ Torrent.prototype._onParsedTorrent = function (parsedTorrent) {
if (self._rechokeIntervalId.unref) self._rechokeIntervalId.unref()
self.emit('infoHash', self.infoHash)
+ if (self.destroyed) return // user might destroy torrent in `infoHash` event handler
if (self.client.listening) {
self._onListening()
@@ -371,7 +372,9 @@ Torrent.prototype._onMetadata = function (metadata) {
self.store = new ImmediateChunkStore(
new self._store(self.pieceLength, {
- torrent: self,
+ torrent: {
+ infoHash: self.infoHash
+ },
files: self.files.map(function (file) {
return {
path: path.join(self.path, file.path),
@@ -464,6 +467,7 @@ Torrent.prototype._verifyPieces = function () {
var self = this
parallelLimit(self.pieces.map(function (_, index) {
return function (cb) {
+ if (self.destroyed) return cb(new Error('torrent is destroyed'))
self.store.get(index, function (err, buf) {
if (err) return cb(null) // ignore error
sha1(buf, function (hash) {
@@ -523,7 +527,7 @@ Torrent.prototype._destroy = function (err, cb) {
self.destroyed = true
self._debug('destroy')
- self.client.remove(self)
+ self.client._remove(self)
clearInterval(self._rechokeIntervalId)
@@ -535,6 +539,10 @@ Torrent.prototype._destroy = function (err, cb) {
self.removePeer(id)
}
+ self.files.forEach(function (file) {
+ if (file instanceof File) file._destroy()
+ })
+
var tasks = self._servers.map(function (server) {
return function (cb) {
server.destroy(cb)
@@ -546,6 +554,7 @@ Torrent.prototype._destroy = function (err, cb) {
self.discovery.destroy(cb)
})
}
+
if (self.store) {
tasks.push(function (cb) {
self.store.close(cb)
@@ -555,14 +564,26 @@ Torrent.prototype._destroy = function (err, cb) {
parallel(tasks, cb)
if (err) {
- // When there is no `torrent.on('error')` listener, emit `client.on('error')` instead.
- // The more-specific, torrent error handler is preferred.
+ // Torrent errors are emitted at `torrent.on('error')`. If there are no 'error' event
+ // handlers on the torrent instance, the error will be emitted at
+ // `client.on('error')`. This prevents crashing the user's program, but it makes it
+ // impossible to determine a client error versus a torrent error (where the client
+ // is still usable afterwards). Users are recommended for errors in both places
+ // to distinguish between the error types.
if (self.listenerCount('error') === 0) {
self.client.emit('error', err)
} else {
self.emit('error', err)
}
}
+
+ self.client = null
+ self.files = []
+ self.discovery = null
+ self.store = null
+ self._rarityMap = null
+ self._peers = null
+ self._servers = null
}
Torrent.prototype.addPeer = function (peer) {