diff options
author | Chocobozzz <me@florianbigard.com> | 2018-09-11 16:27:07 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-09-13 14:05:49 +0200 |
commit | c48e82b5e0478434de30626d14594a97f2402e7c (patch) | |
tree | a78e5272bd0fe4f5b41831e571e02d05f1515b82 /server/helpers/webtorrent.ts | |
parent | a651038487faa838bda3ce04695b08bc65baff70 (diff) | |
download | PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.tar.gz PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.tar.zst PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.zip |
Basic video redundancy implementation
Diffstat (limited to 'server/helpers/webtorrent.ts')
-rw-r--r-- | server/helpers/webtorrent.ts | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts index 1c0cc7058..2fdfd1876 100644 --- a/server/helpers/webtorrent.ts +++ b/server/helpers/webtorrent.ts | |||
@@ -5,44 +5,49 @@ import { createWriteStream, remove } from 'fs-extra' | |||
5 | import { CONFIG } from '../initializers' | 5 | import { CONFIG } from '../initializers' |
6 | import { join } from 'path' | 6 | import { join } from 'path' |
7 | 7 | ||
8 | function downloadWebTorrentVideo (target: { magnetUri: string, torrentName: string }) { | 8 | function downloadWebTorrentVideo (target: { magnetUri: string, torrentName?: string }, timeout?: number) { |
9 | const id = target.magnetUri || target.torrentName | 9 | const id = target.magnetUri || target.torrentName |
10 | let timer | ||
10 | 11 | ||
11 | const path = generateVideoTmpPath(id) | 12 | const path = generateVideoTmpPath(id) |
12 | logger.info('Importing torrent video %s', id) | 13 | logger.info('Importing torrent video %s', id) |
13 | 14 | ||
14 | return new Promise<string>((res, rej) => { | 15 | return new Promise<string>((res, rej) => { |
15 | const webtorrent = new WebTorrent() | 16 | const webtorrent = new WebTorrent() |
17 | let file: WebTorrent.TorrentFile | ||
16 | 18 | ||
17 | const torrentId = target.magnetUri || join(CONFIG.STORAGE.TORRENTS_DIR, target.torrentName) | 19 | const torrentId = target.magnetUri || join(CONFIG.STORAGE.TORRENTS_DIR, target.torrentName) |
18 | 20 | ||
19 | const options = { path: CONFIG.STORAGE.VIDEOS_DIR } | 21 | const options = { path: CONFIG.STORAGE.VIDEOS_DIR } |
20 | const torrent = webtorrent.add(torrentId, options, torrent => { | 22 | const torrent = webtorrent.add(torrentId, options, torrent => { |
21 | if (torrent.files.length !== 1) return rej(new Error('The number of files is not equal to 1 for ' + torrentId)) | 23 | if (torrent.files.length !== 1) { |
24 | if (timer) clearTimeout(timer) | ||
22 | 25 | ||
23 | const file = torrent.files[ 0 ] | 26 | return safeWebtorrentDestroy(webtorrent, torrentId, file.name, target.torrentName) |
27 | .then(() => rej(new Error('The number of files is not equal to 1 for ' + torrentId))) | ||
28 | } | ||
29 | |||
30 | file = torrent.files[ 0 ] | ||
24 | 31 | ||
25 | const writeStream = createWriteStream(path) | 32 | const writeStream = createWriteStream(path) |
26 | writeStream.on('finish', () => { | 33 | writeStream.on('finish', () => { |
27 | webtorrent.destroy(async err => { | 34 | if (timer) clearTimeout(timer) |
28 | if (err) return rej(err) | ||
29 | |||
30 | if (target.torrentName) { | ||
31 | remove(torrentId) | ||
32 | .catch(err => logger.error('Cannot remove torrent %s in webtorrent download.', torrentId, { err })) | ||
33 | } | ||
34 | 35 | ||
35 | remove(join(CONFIG.STORAGE.VIDEOS_DIR, file.name)) | 36 | return safeWebtorrentDestroy(webtorrent, torrentId, file.name, target.torrentName) |
36 | .catch(err => logger.error('Cannot remove torrent file %s in webtorrent download.', file.name, { err })) | 37 | .then(() => res(path)) |
37 | |||
38 | res(path) | ||
39 | }) | ||
40 | }) | 38 | }) |
41 | 39 | ||
42 | file.createReadStream().pipe(writeStream) | 40 | file.createReadStream().pipe(writeStream) |
43 | }) | 41 | }) |
44 | 42 | ||
45 | torrent.on('error', err => rej(err)) | 43 | torrent.on('error', err => rej(err)) |
44 | |||
45 | if (timeout) { | ||
46 | timer = setTimeout(async () => { | ||
47 | return safeWebtorrentDestroy(webtorrent, torrentId, file ? file.name : undefined, target.torrentName) | ||
48 | .then(() => rej(new Error('Webtorrent download timeout.'))) | ||
49 | }, timeout) | ||
50 | } | ||
46 | }) | 51 | }) |
47 | } | 52 | } |
48 | 53 | ||
@@ -51,3 +56,29 @@ function downloadWebTorrentVideo (target: { magnetUri: string, torrentName: stri | |||
51 | export { | 56 | export { |
52 | downloadWebTorrentVideo | 57 | downloadWebTorrentVideo |
53 | } | 58 | } |
59 | |||
60 | // --------------------------------------------------------------------------- | ||
61 | |||
62 | function safeWebtorrentDestroy (webtorrent: WebTorrent.Instance, torrentId: string, filename?: string, torrentName?: string) { | ||
63 | return new Promise(res => { | ||
64 | webtorrent.destroy(err => { | ||
65 | // Delete torrent file | ||
66 | if (torrentName) { | ||
67 | remove(torrentId) | ||
68 | .catch(err => logger.error('Cannot remove torrent %s in webtorrent download.', torrentId, { err })) | ||
69 | } | ||
70 | |||
71 | // Delete downloaded file | ||
72 | if (filename) { | ||
73 | remove(join(CONFIG.STORAGE.VIDEOS_DIR, filename)) | ||
74 | .catch(err => logger.error('Cannot remove torrent file %s in webtorrent download.', filename, { err })) | ||
75 | } | ||
76 | |||
77 | if (err) { | ||
78 | logger.warn('Cannot destroy webtorrent in timeout.', { err }) | ||
79 | } | ||
80 | |||
81 | return res() | ||
82 | }) | ||
83 | }) | ||
84 | } | ||