From c48e82b5e0478434de30626d14594a97f2402e7c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 11 Sep 2018 16:27:07 +0200 Subject: Basic video redundancy implementation --- server/helpers/webtorrent.ts | 61 +++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'server/helpers/webtorrent.ts') 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' import { CONFIG } from '../initializers' import { join } from 'path' -function downloadWebTorrentVideo (target: { magnetUri: string, torrentName: string }) { +function downloadWebTorrentVideo (target: { magnetUri: string, torrentName?: string }, timeout?: number) { const id = target.magnetUri || target.torrentName + let timer const path = generateVideoTmpPath(id) logger.info('Importing torrent video %s', id) return new Promise((res, rej) => { const webtorrent = new WebTorrent() + let file: WebTorrent.TorrentFile const torrentId = target.magnetUri || join(CONFIG.STORAGE.TORRENTS_DIR, target.torrentName) const options = { path: CONFIG.STORAGE.VIDEOS_DIR } const torrent = webtorrent.add(torrentId, options, torrent => { - if (torrent.files.length !== 1) return rej(new Error('The number of files is not equal to 1 for ' + torrentId)) + if (torrent.files.length !== 1) { + if (timer) clearTimeout(timer) - const file = torrent.files[ 0 ] + return safeWebtorrentDestroy(webtorrent, torrentId, file.name, target.torrentName) + .then(() => rej(new Error('The number of files is not equal to 1 for ' + torrentId))) + } + + file = torrent.files[ 0 ] const writeStream = createWriteStream(path) writeStream.on('finish', () => { - webtorrent.destroy(async err => { - if (err) return rej(err) - - if (target.torrentName) { - remove(torrentId) - .catch(err => logger.error('Cannot remove torrent %s in webtorrent download.', torrentId, { err })) - } + if (timer) clearTimeout(timer) - remove(join(CONFIG.STORAGE.VIDEOS_DIR, file.name)) - .catch(err => logger.error('Cannot remove torrent file %s in webtorrent download.', file.name, { err })) - - res(path) - }) + return safeWebtorrentDestroy(webtorrent, torrentId, file.name, target.torrentName) + .then(() => res(path)) }) file.createReadStream().pipe(writeStream) }) torrent.on('error', err => rej(err)) + + if (timeout) { + timer = setTimeout(async () => { + return safeWebtorrentDestroy(webtorrent, torrentId, file ? file.name : undefined, target.torrentName) + .then(() => rej(new Error('Webtorrent download timeout.'))) + }, timeout) + } }) } @@ -51,3 +56,29 @@ function downloadWebTorrentVideo (target: { magnetUri: string, torrentName: stri export { downloadWebTorrentVideo } + +// --------------------------------------------------------------------------- + +function safeWebtorrentDestroy (webtorrent: WebTorrent.Instance, torrentId: string, filename?: string, torrentName?: string) { + return new Promise(res => { + webtorrent.destroy(err => { + // Delete torrent file + if (torrentName) { + remove(torrentId) + .catch(err => logger.error('Cannot remove torrent %s in webtorrent download.', torrentId, { err })) + } + + // Delete downloaded file + if (filename) { + remove(join(CONFIG.STORAGE.VIDEOS_DIR, filename)) + .catch(err => logger.error('Cannot remove torrent file %s in webtorrent download.', filename, { err })) + } + + if (err) { + logger.warn('Cannot destroy webtorrent in timeout.', { err }) + } + + return res() + }) + }) +} -- cgit v1.2.3