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

fs.createWriteStream is creating file but not writing to it #1641

Closed
ORESoftware opened this issue Nov 28, 2018 · 12 comments
Closed

fs.createWriteStream is creating file but not writing to it #1641

ORESoftware opened this issue Nov 28, 2018 · 12 comments

Comments

@ORESoftware
Copy link

I have this:

const fs = require('fs');
const strm = fs.createWriteStream(file);
strm.write('foop\n');
strm.write('bop\n');
strm.end()

for some reason, the file gets created, but no data gets written to the file. Why would that happen?

@ORESoftware
Copy link
Author

This problem seems to occur on both node.js version 10 and 11.

I tried this too:

const t = new Transform({
  transform(chunk, enc, cb){
    cb(null,chunk);
  }
});

t.pipe(strm);

t.write('foop')
t.push('bar');
t.end();

the file gets created, but nothing gets written to it :(

@ORESoftware
Copy link
Author

ORESoftware commented Nov 28, 2018

if I put a logging statement here:

const t = new Transform({
  transform(chunk, enc, cb){
    console.log({chunk: String(chunk)});   //  <<< logging
    cb(null, String(chunk));
  }
});

then my logging statement does log all the data that I want to go to the file, so the data is being written to the transform stream but not to the file! :(

@gireeshpunathil
Copy link
Member

not reproducible with v10.5 on mac. which platform do you use?
$ cat 1641.js

const fs = require('fs');
const strm = fs.createWriteStream('ore.txt');
strm.write('foop\n');
strm.write('bop\n');
strm.end()

$ node -v
v10.5.0
$ node 1641.js
$ l ore.txt
-rw-r--r-- 1 gireeshpunathil staff 9 Nov 28 13:02 ore.txt
$ cat ore.txt

foop
bop

$

@ORESoftware
Copy link
Author

Yeah my current guess is that some error is failing silently in the program before it has a chance to write all the files out...but I am not sure yet..I am on Ubuntu...Node version 10/11.

@ORESoftware
Copy link
Author

@gireeshpunathil ughh it was a simple case of calling process.exit() too soon, see:
nodejs/node#24688

thanks

@gireeshpunathil
Copy link
Member

@ORESoftware - went through nodejs/node#2468 , thanks for the full context!

As I see it, the event infrastructure (event loop) could be in probable states when process.exit() is called:

  1. no events are registered, and no events are fired. So process.exit === natural exit

  2. no events are fired (yet), but there are events that are registered (a web server running a service loop for example). Only way to exit node is via process.exit(). Most common scenario

  3. events are fired, and is being worked upon (by helper threads for example). Main thread is invoked with process.exit(). work is discarded and helpers are called to quiesce. I guess your scenario?

This also covers the many-times-reported issue of truncated console output on CLI programs (ref:
nodejs/node#19218, nodejs/node#784, nodejs/node#6456 and nodejs/node#6379)

There is something we can do to improve the user experience on case 3, don't know what is the right semantics though.

@ORESoftware
Copy link
Author

@gireeshpunathil for the purposes of this feature, what would be the difference between 2 and 3?

@gireeshpunathil
Copy link
Member

@ORESoftware - In event driven programming, a program would have (ideally) one or more event registrations at any given point in time.

In the most common use cases, the characteristic feature of these events are:

  • they don't have defined lifecycles : start at some convenient point, but run for ever.
  • the (physical) phenomena those event represent (wait for) are external to the process or machine

classical example is the webserver's service loop (server.createServer((q, r) => ...)

It is an over-kill to inform / warn about the presence of such a pending event handler on process.exit.

In case 3, and event is registered, as well as triggered, and being actioned upon. We are exiting in the middle - which warrants some form of functional (or documented) support.

@lopugit
Copy link

lopugit commented Jul 14, 2019

let fs = require('fs')
let { Console } = require('console')
// fs.writeFileSync('./node/test/outputs/searches.log', 'tetet')
// fs.writeFileSync('./node/test/outputs/searches.log.error.log', 'teteet')
const output = fs.createWriteStream('./node/test/outputs/searches.log');
const errorOutput = fs.createWriteStream('./node/test/outputs/searches.log.error.log');
console = new Console(output, errorOutput);

// let query = "🌿 🌻 🍓"
let query = "one two three"
// let query = "LOL LMAO LMFAO"
let words = query.split(' ')
let debug = global.debug || false
let smarts = require('smarts')()
let ps = require('prettyjson')

console.log('\n start \n')

let args = { 
	array: words, 
	combinations: [], 
	combinationsA: [] 
}

let codes = [0,1]
let permutationsCodes = getVariablePermutations(codes, args.array.length)
let permutations = []
for(permutationCodeIndex in permutationsCodes){
	permutations[permutationCodeIndex] = []
	for(includeIndex in permutationsCodes[permutationCodeIndex]){
		if(permutationsCodes[permutationCodeIndex][includeIndex]){
			permutations[permutationCodeIndex].push(args.array[includeIndex])
			// console.log('args.array[includeIndex] ', args.array[includeIndex])
		}
	}
}

let searchPermutations = []
let i = 0
for(permutationIndex in permutations){
	// generate the insertion sequence for regex or any other symbols, [0,1,1,0], [0,0,1,0] etc..
	// we use length + 1 to create the last index trailing regex edge case 
	let insertionCodes = getVariablePermutations(codes, permutations[permutationIndex].length+1)
	for(insertionCodeIndex in insertionCodes){
		// create the array for the current search permutation
		searchPermutations.push([]) 
		// iterator for the current search permutation section 
		let b = 0
		// create first search permutation section
		searchPermutations[i].push([])
		// loop over insertion indexes to know when to split or insert into the search query
		for(insertionIndex in insertionCodes[insertionCodeIndex]){
			// if the insertion index is less than the length then we're within the last index edge case for trailing regex
			if(insertionIndex < permutations[permutationIndex].length){
				// if the insertion index is not 0 then we insert something, in this case only 0/1 where 1 is a regex for match any .*
				if(insertionCodes[insertionCodeIndex][insertionIndex]){
					// if the insertion index isn't 0, we add two more arrays to split away from the previous search string for the new regex section plus also add a new search string section
					if(insertionIndex !== '0'){
						b++
						searchPermutations[i].push([])
						searchPermutations[i][b].push('/.*/')
						b++
						searchPermutations[i].push([])
						searchPermutations[i][b].push(permutations[permutationIndex][insertionIndex])
					} 
					// if we are at the start of the search string we exhibit the leading regex edge case behaviour where you don't need to create a new array for the regex
					else {
						searchPermutations[i][b].push('/.*/')
						b++
						searchPermutations[i].push([permutations[permutationIndex][insertionIndex]])
					}
				} 
				// if there's nothing to insert, we push the next search string into the current non-disturbed sub-search string array
				else {
					searchPermutations[i][b].push(permutations[permutationIndex][insertionIndex])
				}
			} 
			// else if the insertion index is greater than the length of the search string permutation then we exhibit the last index edge case behaviour for trailing regex
			else if(insertionCodes[insertionCodeIndex][insertionIndex]){
				b++
				searchPermutations[i].push([])
				searchPermutations[i][b].push('/.*/')
			}
		} 
		i++
	} 
}

for(test in searchPermutations){
	console.log(searchPermutations[test])
}
console.log(searchPermutations.length)

function getVariablePermutations(list, maxLen) {
    // Copy initial values as arrays
		if(maxLen == 0) return []
    var perm = list.map(function(val) {
        return [val];
    });
    // Our permutation generator
    var generate = function(perm, maxLen, currLen) {
        // Reached desired length
        if (currLen === maxLen) {
            return perm;
        }
        // For each existing permutation
        for (var i = 0, len = perm.length; i < len; i++) {
            var currPerm = perm.shift();
            // Create new permutation
            for (var k = 0; k < list.length; k++) {
                perm.push(currPerm.concat(list[k]));
            }
        }
        // Recurse
        return generate(perm, maxLen, currLen + 1);
    };
    // Start with size 1 because of initial values
    return generate(perm, maxLen, 1);
};

process.exit()

this is too soon??!?!?!?!?! I fixed this issue by commenting the process.exit, but what??

@szekelygobe
Copy link

Is there a solution for this ? I'm trying to log some stuff into a file using fs.createWriteStream before exiting the process.
The logfile is created, the stream.write() is not performed and the script exits.
How can I solve this ?

@provCristianMaluenda
Copy link

Is there a solution for this ? I'm trying to log some stuff into a file using fs.createWriteStream before exiting the process.
The logfile is created, the stream.write() is not performed and the script exits.
How can I solve this ?

@szekelygobe
You can close the stream and wait until it is done.

async close():Promise<void>{
        this.stream.close();
        return new Promise((resolve, reject)=>{
            this.stream.once('close', ()=>{
                resolve();
            });
        });
    }

@seantcanavan
Copy link

@provCristianMaluenda thank you so much for this!

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

No branches or pull requests

6 participants