Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calls to asynchronous fs.appendFile() overwrite each other #37

Open
jwngr opened this issue May 4, 2015 · 1 comment
Open

Calls to asynchronous fs.appendFile() overwrite each other #37

jwngr opened this issue May 4, 2015 · 1 comment
Labels

Comments

@jwngr
Copy link

jwngr commented May 4, 2015

Sequential calls to the asynchronous fs.appendFile() using this mocked library appear to conflict and overwrite each other, while the non-mocked library does not have this behavior.

Here is the behavior with the regular fs library:

var fs = require('fs');

var filename = './foo.txt';

for (var i = 0; i < 5; ++i) {
  fs.appendFile(filename, 'iteration' + i + '\n', function(error) {
    if (error) {
      console.log('Error:', error)
    }
    console.log('Added');
  });
}

setTimeout(function() {
  fs.readFile(filename, 'utf8', function (err, data) {
    if (err) throw err;
    console.log(data);
  });
}, 1000);

This outputs the following:

Added
Added
Added
Added
Added
iteration0
iteration4
iteration1
iteration3
iteration2

Note that this output is non-deterministic because the five writes could complete in any order. But that is tangential to this issue.

Now, using the mock-fs library:

var fs = require('fs');
var mockFs = require('mock-fs');

var filename = './foo.txt';

mockFs({
  '.': {}
});

for (var i = 0; i < 5; ++i) {
  fs.appendFile(filename, 'iteration' + i + '\n', function(error) {
    if (error) {
      console.log('Error:', error)
    }
    console.log('Added');
  });
}

setTimeout(function() {
  fs.readFile(filename, 'utf8', function (err, data) {
    if (err) throw err;
    console.log(data);
  });
}, 1000);

This outputs:

Added
Added
Added
Added
Added
iteration4

As you can see, only the last append succeeds. If we use the synchronous mocked version, all is well:

var fs = require('fs');
var mockFs = require('mock-fs');

var filename = './foo.txt';

mockFs({
  '.': {}
});

for (var i = 0; i < 5; ++i) {
  fs.appendFileSync(filename, 'iteration' + i + '\n');
}

setTimeout(function() {
  fs.readFile(filename, 'utf8', function (err, data) {
    if (err) throw err;
    console.log(data);
  });
}, 1000);

Outputs:

iteration0
iteration1
iteration2
iteration3
iteration4

I would like to use the asynchronous version of appendFile() because I don't care about the ordering of items, just that they all are there. I also don't want to block the process while the write is happening, which is what the synchronous version does.

@tschaub tschaub added the bug label May 7, 2015
@jwngr
Copy link
Author

jwngr commented Jun 3, 2015

Hey @tschaub - if you can point me to some code lines or let me know what you think may be the issue here, I'd be happy to put together a PR for this. I assume the issue here is that each call to appendFile() is actually overwriting the file instead of appending to it. We don't run into this issue with appendFileSync() since it blocks the process until the append is done, before any other appends can be started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants