improve native isolation
This commit is contained in:
parent
3f57682a9b
commit
9748b98163
15 changed files with 341 additions and 95 deletions
|
|
@ -199,6 +199,49 @@ async function chmodTree(root) {
|
|||
return { files, dirs }
|
||||
}
|
||||
|
||||
// One file, streamed, with byte progress: copyFile says nothing until a
|
||||
// multi-gigabyte copy is over. The bytes land on a .part name and are renamed
|
||||
// at the end, so nothing can ever read a half-written document.
|
||||
async function copyFileProgress(src, dst, onProgress) {
|
||||
const stat = await fsp.stat(src)
|
||||
if (!stat.isFile()) throw new Error('not a file: ' + src)
|
||||
const gate = onProgress ? progressGate(onProgress) : null
|
||||
await fsp.mkdir(path.dirname(dst), { recursive: true })
|
||||
const part = dst + '.part'
|
||||
let bytes = 0
|
||||
try {
|
||||
await new Promise((resolve, reject) => {
|
||||
const input = fs.createReadStream(src)
|
||||
const output = fs.createWriteStream(part)
|
||||
const fail = err => {
|
||||
input.destroy()
|
||||
output.destroy()
|
||||
reject(err)
|
||||
}
|
||||
input.on('error', fail)
|
||||
output.on('error', fail)
|
||||
input.on('data', chunk => {
|
||||
bytes += chunk.length
|
||||
if (gate) gate({ done: 0, bytes }, false)
|
||||
})
|
||||
output.on('finish', resolve)
|
||||
input.pipe(output)
|
||||
})
|
||||
await fsp.chmod(part, stat.mode & 0o777)
|
||||
await fsp.rename(part, dst)
|
||||
} catch (err) {
|
||||
try {
|
||||
await fsp.rm(part, { force: true })
|
||||
} catch {}
|
||||
throw err
|
||||
}
|
||||
if (gate) {
|
||||
gate({ done: 1, bytes: stat.size }, true)
|
||||
gate.done()
|
||||
}
|
||||
return { files: 1, bytes: stat.size }
|
||||
}
|
||||
|
||||
// Delete deepest-first with progress through onProgress; symlinks are
|
||||
// unlinked, never followed.
|
||||
async function removeTree(root, onProgress) {
|
||||
|
|
@ -266,5 +309,5 @@ async function removeTree(root, onProgress) {
|
|||
return { files, dirs, bytes }
|
||||
}
|
||||
|
||||
module.exports = { pathExists, dedupeDir, copyTree, treeSize, removeTree, chmodTree, progressGate, mapLimit }
|
||||
module.exports = { pathExists, dedupeDir, copyTree, copyFileProgress, treeSize, removeTree, chmodTree, progressGate, mapLimit }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue