Skip to content

writeFile corrupts data with high frequency requests on same file #2346

@anywhichway

Description

@anywhichway
  • Version: v12.13.0
  • Platform: 64-bit (Windows 10)
  • Subsystem: fs
const fs = require('fs'),
  assert = require('assert')
  file = './foo.json';

const numbers = [];
async function verify() {
	const number = Math.random();
	numbers.push(number);
	await fs.promises.writeFile(file, JSON.stringify({number}), "utf-8");
	const data = JSON.parse(fs.readFileSync(file,"utf-8"));
	// since we await the write and then read synchronously immediately
	// we expect the data to be what was just written
	assert.equal(data.number,number);
	// what is actually experienced is a corrupt file
	// SyntaxError: Unexpected token } in JSON at position 29
	// Modifying the read to be asynchronous will also throw an error
	// but this is expected since another write may have been done before the read.
	// Expected behavior: The file should never be in a partially written state
	// once the writeFile await is resolved. We presume that internally, Node is
	// not truncating the file to the new length prior to resolving the Promise.
}

try {
	fs.unlinkSync(file);
} catch(e) {
	if(e.code!=="ENOENT") {
		throw(e)
	}
}
(async () => {
	for (var i = 0; i < 10; i++) {
		await verify();
	}
	console.log("await loop ok")
})().then(() => {
	const promises = [];
	for (var i = 0; i < 10; i++) {
		promises.push(verify());
	}
	Promise.all(promises)
		.then(() => console.log("no await loop ok"))
		.catch((e) => {
			console.log(numbers);
			console.error(e);
		})
})

Although we have not been able to reproduce it with a small code sample, under high load we have experienced the same corruption when both the write and the read use the fs.promises module and the writes and reads are always awaited with moderate file content sizes, e.g. 1K or less. For now, if we make everything synchronous, we have no issues. This is a big step up from earlier versions of node; however, it obviously has a negative impact on our app overall.

A similar issue is documented here: nodejs/node-v0.x-archive#4965

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions