Skip to content

Commit eeb6e2d

Browse files
author
Sergey Tatarintsev
committed
Improve memory consumption of file middleware
Buffers.concat creates a new buffer. On a large project, when using resolver cache and pack store, total size of buffer can reach hundreds of megabytes. Use streaming write instead.
1 parent 8038555 commit eeb6e2d

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

lib/serialization/FileMiddleware.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,32 @@ const readSection = (filename, file, offset, size, callback) => {
255255
});
256256
};
257257

258+
const writeBuffers = (fileHandle, buffers, callback) => {
259+
const stream = fs.createWriteStream(null, {
260+
fd: fileHandle,
261+
autoClose: false
262+
});
263+
let index = 0;
264+
265+
const doWrite = function() {
266+
let canWriteMore = true;
267+
while (canWriteMore && index < buffers.length) {
268+
const chunk = buffers[index++];
269+
canWriteMore = stream.write(chunk);
270+
}
271+
272+
if (index < buffers.length) {
273+
stream.once("drain", doWrite);
274+
} else {
275+
stream.end();
276+
}
277+
};
278+
279+
stream.on("error", err => callback(err));
280+
stream.on("finish", () => callback(null));
281+
doWrite();
282+
};
283+
258284
class FileMiddleware extends SerializerMiddleware {
259285
/**
260286
* @param {any[]} data data items
@@ -296,7 +322,7 @@ class FileMiddleware extends SerializerMiddleware {
296322
mkdirp(path.dirname(filename), err => {
297323
if (err) return reject(err);
298324
fileManager.addJob(filename, true, (file, callback) => {
299-
fs.writeFile(file, Buffer.concat(buffers), err => {
325+
writeBuffers(file, buffers, err => {
300326
if (err) return callback(err);
301327
resolve(true);
302328
callback();

0 commit comments

Comments
 (0)