-1

I have some code that I need to wrap with mine, the original code is creating a WriteStream this way -

function createLog() {
    this.stream = this.fs.createWriteStream(this.logFilePath, {flags: 'a'});
    this.stream.write('log content');
    this.stream.close();
}

function testLog(){ 
    this.createLog();
    // Here I want to wait until the file is closed
    // something like this.stream.waitToBeClosed();
    let text = fs.readFileSync(this.logFilePath, 'utf-8');
    return text.match(
        `log content`
    );
}

then, in the end of the function the stream is closed using -

this.stream.close()

I need to use that function, and then examine the log file and verify it contain all the required data, but unfortunately sometimes the last lines are missing. I believe it's because the stream is still not closed when I open the file for reading.

I know that I can use stream.on('finish'... to execute code when the stream is closed, but I am not supposed to touch the createLog code... (As I am writing a test for it) and before the execution of the createLog function I have no access to the stream object.

Is there a way that I can wait until the stream is closed from outside the original function?

Meir Tolpin
  • 325
  • 2
  • 13
  • Please show us the whole function that contains this code. It's unclear from your description why you can just use the `finish` or `close` events. Perhaps we need to see more context or know more about what you can and can't modify (and why). – jfriend00 Mar 20 '23 at 23:42
  • Are you sure it is a close issue? Did you try a fsync? https://nodejs.org/api/fs.html#filehandledatasync – Asad Awadia Mar 21 '23 at 02:55
  • @jfriend00 added code snippets to the post, is it more clear now ? – Meir Tolpin Mar 21 '23 at 07:47

1 Answers1

-1

If you really can't modify createLog() to provide the caller a means to know when it's done (which is really the right way to do things), then because the stream is in the instance data, you could modify testLog() like this:

async function testLog() {
    this.createLog();
    // wait for the stream to complete its work
    await new Promise((resolve, reject) => {
        this.stream.on('close', resolve).on('error', reject);
    });
    let text = fs.readFileSync(this.logFilePath, 'utf-8');
    return text.match('log content`);
}

Note, that testLog() is now async and thus will return a promise that resolves with the text.match() results.

jfriend00
  • 683,504
  • 96
  • 985
  • 979