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
path: root/lib
diff options
context:
space:
mode:
authorDiego Rodríguez Baquero <diegorbaquero@gmail.com>2016-04-03 02:02:00 +0300
committerDiego Rodríguez Baquero <diegorbaquero@gmail.com>2016-04-03 02:02:00 +0300
commit7205c151a044d121f529cac653bcf52a0a222a7a (patch)
tree3ef0d3675003ca6deb3dbae1311ceb0f34b2be39 /lib
parentb1fec4de2da98e418efa9cac32f65e141c5decd6 (diff)
parent00da34d0b80fd0a2b5ad9c07e334fb52de6a8e7b (diff)
Merge branch 'master' into max-web-conns-default
Diffstat (limited to 'lib')
-rw-r--r--lib/peer.js4
-rw-r--r--lib/torrent.js94
2 files changed, 79 insertions, 19 deletions
diff --git a/lib/peer.js b/lib/peer.js
index aafbabe..06786c5 100644
--- a/lib/peer.js
+++ b/lib/peer.js
@@ -4,8 +4,8 @@ var Wire = require('bittorrent-protocol')
var WebConn = require('./webconn')
-var CONNECT_TIMEOUT_TCP = 25000
-var CONNECT_TIMEOUT_WEBRTC = 5000
+var CONNECT_TIMEOUT_TCP = 5000
+var CONNECT_TIMEOUT_WEBRTC = 25000
var HANDSHAKE_TIMEOUT = 25000
/**
diff --git a/lib/torrent.js b/lib/torrent.js
index 2bff2e1..622b58f 100644
--- a/lib/torrent.js
+++ b/lib/torrent.js
@@ -5,12 +5,12 @@ module.exports = Torrent
var addrToIPPort = require('addr-to-ip-port')
var BitField = require('bitfield')
var ChunkStoreWriteStream = require('chunk-store-stream/write')
-var cpus = require('cpus')
var debug = require('debug')('webtorrent:torrent')
var Discovery = require('torrent-discovery')
var EventEmitter = require('events').EventEmitter
var extend = require('xtend')
var extendMutable = require('xtend/mutable')
+var fs = require('fs')
var FSChunkStore = require('fs-chunk-store') // browser: `memory-chunk-store`
var ImmediateChunkStore = require('immediate-chunk-store')
var inherits = require('inherits')
@@ -24,7 +24,6 @@ var pathExists = require('path-exists') // browser exclude
var Piece = require('torrent-piece')
var pump = require('pump')
var randomIterate = require('random-iterate')
-var reemit = require('re-emitter')
var sha1 = require('simple-sha1')
var uniq = require('uniq')
var ut_metadata = require('ut_metadata')
@@ -46,6 +45,8 @@ var PIPELINE_MAX_DURATION = 1
var RECHOKE_INTERVAL = 10000 // 10 seconds
var RECHOKE_OPTIMISTIC_DURATION = 2 // 30 seconds
+var FILESYSTEM_CONCURRENCY = 2
+
var TMP = typeof pathExists.sync === 'function'
? path.join(pathExists.sync('/tmp') ? '/tmp' : os.tmpDir(), 'webtorrent')
: '/tmp/webtorrent'
@@ -59,7 +60,6 @@ inherits(Torrent, EventEmitter)
*/
function Torrent (torrentId, client, opts) {
EventEmitter.call(this)
- if (!debug.enabled) this.setMaxListeners(0)
this.client = client
this._debugId = this.client.peerId.slice(32)
@@ -100,6 +100,9 @@ function Torrent (torrentId, client, opts) {
// for cleanup
this._servers = []
+ // optimization: don't recheck every file if it hasn't changed
+ this._fileModtimes = opts.fileModtimes
+
if (torrentId !== null) this._onTorrentId(torrentId)
}
@@ -298,10 +301,11 @@ Torrent.prototype._onSwarmListening = function () {
// begin discovering peers via DHT and trackers
self.discovery = new Discovery({
+ infoHash: self.infoHash,
announce: self.announce,
+ peerId: self.client.peerId,
dht: !self.private && self.client.dht,
tracker: self.client.tracker && trackerOpts,
- peerId: self.client.peerId,
port: self.client.torrentPort
})
self.discovery.on('error', function (err) {
@@ -314,11 +318,19 @@ Torrent.prototype._onSwarmListening = function () {
})
// expose discovery events
- reemit(self.discovery, self, ['trackerAnnounce', 'dhtAnnounce', 'warning'])
+ self.discovery.on('trackerAnnounce', function () {
+ self.emit('trackerAnnounce')
+ })
+ self.discovery.on('dhtAnnounce', function () {
+ self.emit('dhtAnnounce')
+ })
+ self.discovery.on('warning', function (err) {
+ self.emit('warning', err)
+ })
- // if full metadata was included in initial torrent id, use it
+ // if full metadata was included in initial torrent id, use it immediately. Otherwise,
+ // wait for torrent-discovery to find peers and ut_metadata to get the metadata.
if (self.info) self._onMetadata(self)
- else self.discovery.setTorrent(self.infoHash)
self.emit('listening', self.client.torrentPort)
}
@@ -346,9 +358,6 @@ Torrent.prototype._onMetadata = function (metadata) {
self._processParsedTorrent(parsedTorrent)
self.metadata = self.torrentFile
- // pass full torrent metadata to discovery module
- self.discovery.setTorrent(self)
-
// add web seed urls (BEP19)
self.urlList.forEach(function (url) {
self.addWebSeed(url)
@@ -398,7 +407,56 @@ Torrent.prototype._onMetadata = function (metadata) {
})
self._debug('verifying existing torrent data')
- parallelLimit(self.pieces.map(function (piece, index) {
+ if (self._fileModtimes && self._store === FSChunkStore) {
+ // don't verify if the files haven't been modified since we last checked
+ self.getFileModtimes(function (err, fileModtimes) {
+ if (err) return self._onError(err)
+
+ var unchanged = self.files.map(function (_, index) {
+ return fileModtimes[index] === self._fileModtimes[index]
+ }).every(function (x) {
+ return x
+ })
+
+ if (unchanged) {
+ for (var index = 0; index < self.pieces.length; index++) {
+ self._markVerified(index)
+ }
+ self._onStore()
+ } else {
+ self._verifyPieces()
+ }
+ })
+ } else {
+ self._verifyPieces()
+ }
+
+ self.emit('metadata')
+}
+
+/*
+ * Gets the last modified time of every file on disk for this torrent.
+ * Only valid in Node, not in the browser.
+ */
+Torrent.prototype.getFileModtimes = function (cb) {
+ var self = this
+ var ret = []
+ parallelLimit(self.files.map(function (file, index) {
+ return function (cb) {
+ fs.stat(path.join(self.path, file.path), function (err, stat) {
+ ret[index] = stat && stat.mtime.getTime()
+ cb(err)
+ })
+ }
+ }), FILESYSTEM_CONCURRENCY, function (err) {
+ self._debug('done getting file modtimes')
+ cb(err, ret)
+ })
+}
+
+Torrent.prototype._verifyPieces = function () {
+ var self = this
+ parallelLimit(self.pieces.map(function (_, index) {
return function (cb) {
self.store.get(index, function (err, buf) {
if (err) return cb(null) // ignore error
@@ -406,9 +464,7 @@ Torrent.prototype._onMetadata = function (metadata) {
if (hash === self._hashes[index]) {
if (!self.pieces[index]) return
self._debug('piece verified %s', index)
- self.pieces[index] = null
- self._reservations[index] = null
- self.bitfield.set(index, true)
+ self._markVerified(index)
} else {
self._debug('piece invalid %s', index)
}
@@ -416,13 +472,17 @@ Torrent.prototype._onMetadata = function (metadata) {
})
})
}
- }), cpus().length, function (err) {
+ }), FILESYSTEM_CONCURRENCY, function (err) {
if (err) return self._onError(err)
self._debug('done verifying')
self._onStore()
})
+}
- self.emit('metadata')
+Torrent.prototype._markVerified = function (index) {
+ this.pieces[index] = null
+ this._reservations[index] = null
+ this.bitfield.set(index, true)
}
/**
@@ -470,7 +530,7 @@ Torrent.prototype.destroy = function (cb) {
})
if (self.swarm) tasks.push(function (cb) { self.swarm.destroy(cb) })
- if (self.discovery) tasks.push(function (cb) { self.discovery.stop(cb) })
+ if (self.discovery) tasks.push(function (cb) { self.discovery.destroy(cb) })
if (self.store) tasks.push(function (cb) { self.store.close(cb) })
parallel(tasks, cb)