feat(transfer): download everything to tmp dir to prevent unfinish transfers

This commit is contained in:
Alexey Kasyanchuk
2018-09-02 08:17:44 +03:00
parent 7098bdd0b3
commit 4334463e3c
2 changed files with 47 additions and 12 deletions

View File

@ -0,0 +1,15 @@
const fs = require('fs')
module.exports = function deleteFolderRecursive(path) {
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach(function(file, index){
var curPath = path + "/" + file;
if (fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
};

View File

@ -12,6 +12,7 @@ const ph = require('path')
const directoryFilesRecursive = require('./directoryFilesRecursive') const directoryFilesRecursive = require('./directoryFilesRecursive')
const {promisify} = require('util'); const {promisify} = require('util');
const mkdirp = promisify(require('mkdirp')) const mkdirp = promisify(require('mkdirp'))
const deleteFolderRecursive = require('./deleteFolderRecursive')
class p2p { class p2p {
constructor(send = () => {}) constructor(send = () => {})
@ -413,7 +414,7 @@ class p2p {
return () => callbacks.forEach(callback => callback()) return () => callbacks.forEach(callback => callback())
} }
file(path, targetPath, remotePeer) file(path, targetPath, remotePeer, parent)
{ {
if(!this.dataDirectory) if(!this.dataDirectory)
{ {
@ -430,16 +431,19 @@ class p2p {
logT('transfer', 'get file request', path) logT('transfer', 'get file request', path)
const promise = new Promise(async (resolve) => const promise = new Promise(async (resolve) =>
{ {
const filePath = this.dataDirectory + '/' + (targetPath || path) const realPath = (targetPath || path).replace(/\\/g, '/')
// recreate directory to file if not exist const filePath = this.dataDirectory + '/' + realPath
await mkdirp(ph.dirname(filePath)) const tmpPath = this.dataDirectory + '/' + realPath.split('/').map(p => p + '.tmp').join('/')
// create temporary directory and file for downloading
await mkdirp(ph.dirname(tmpPath))
let fileStream let fileStream
if(!fs.existsSync(filePath) || !fs.lstatSync(filePath).isDirectory()) if(!fs.existsSync(tmpPath) || !fs.lstatSync(tmpPath).isDirectory())
fileStream = fs.createWriteStream(filePath) fileStream = fs.createWriteStream(tmpPath)
let peer = null let peer = null
let firstTransfer = false let firstTransfer = false
let deleteCallback = (remotePeer || this).emit('file', {path}, (chunk, nil, addr) => { let deleteCallback = (remotePeer || this).emit('file', {path}, async (chunk, nil, addr) => {
if(peer && addr !== peer) if(peer && addr !== peer)
{ {
logT('transfer', 'ignore other peers responce', addr.peerId) logT('transfer', 'ignore other peers responce', addr.peerId)
@ -454,8 +458,20 @@ class p2p {
fileStream.end() fileStream.end()
if(firstTransfer) // данные передало до этого, значит файл целый if(firstTransfer) // данные передало до этого, значит файл целый
{ {
const renameCallback = async () => {
await mkdirp(ph.dirname(filePath))
fs.renameSync(tmpPath, filePath)
}
if(parent)
{
resolve(renameCallback)
}
else
{
await renameCallback()
resolve(true) resolve(true)
} }
}
return return
} }
@ -466,14 +482,18 @@ class p2p {
logT('transfer', 'get folder content', filesList) logT('transfer', 'get folder content', filesList)
deleteCallback() deleteCallback()
const transferFiles = () => { const transferFiles = () => {
Promise.all(filesList.map(file => this.file(file, null, addr))).then(() => { Promise.all(filesList.map(file => this.file(file, null, addr, true))).then(async (files) => {
// files transfers, now move it from tmp dir
Promise.all(files.map((renameCallback) => renameCallback())).then(() => {
deleteFolderRecursive(tmpPath)
logT('transfer', 'finish transfer all files from folder') logT('transfer', 'finish transfer all files from folder')
resolve() resolve()
}) })
})
} }
if(fileStream) if(fileStream)
fileStream.end(null, null, () => { fileStream.end(null, null, () => {
fs.unlinkSync(filePath) fs.unlinkSync(tmpPath)
transferFiles() transferFiles()
}) })
else else