Skip to content

Output data lost from spawned process if process ends before all data read #9633

@IanCollins

Description

@IanCollins
  • Version: v6.9.1
  • Platform: Linux bld-1604 4.3.0 BrandZ virtual linux x86_64 x86_64 x86_64 GNU/Linux (Ubuntu 16.04)
  • Subsystem: child_process

We have a gulp build step that converts a protobuf file to JSON using a tool 'pbjs'. We are seeing a truncated output file. This problem only appears on Linux, Windows builds aren't affected.

The conversion is called thus:

gulp.task('create-proto-json', ['prepare-proto-sources'], function () {
    var pbjs_cmd = path.resolve('node_modules/protobufjs/bin/pbjs');
    return gulp.src(targetFolder + 'proto-xxx.proto')
        .pipe(exec('node "' + pbjs_cmd + '" ' + path.normalize(targetFolder + 'proto-xxx.proto') + ' --target=json', { pipeStdout: true, maxBuffer: 1000000 }))
        .pipe(rename({extname: '.json'}))
        .pipe(gulp.dest(targetFolder));
});

The conversion generates over 800K of output, but only 219K are written to the output file. Running strace on the command give some hint:

[pid  2112]      0.002595 write(1, "{\n    \"package\": \"com.xxx\",\n   "..., 816819 <unfinished ...>
[pid  2095]      0.000396 <... epoll_wait resumed> [{EPOLLIN, {u32=14, u64=14}}], 1024, -1) = 1
[pid  2112]      0.000043 <... write resumed> ) = 219264
[pid  2095]      0.000090 read(14,  <unfinished ...>
[pid  2112]      0.000123 write(2, " \n", 2 <unfinished ...>

Changing exec to spawn and logging the stdout reads showed 3 64K reads and one 22K read before the stream closed:

var json = spawn(pbjs_cmd, [path.normalize(targetFolder + 'proto-xxx.proto'), '--target=json']);
json.stdout.on('data', function(data) { file.write(data); console.log(data.length);});
json.stdout.on('end', function(data)  { file.end(); console.log('End'); });
json.stderr.on('data', function(data) { console.log(data.toString()); });
json.on('exit', function(code) { console.log('Exit: ' + code ); });
 Processing: app/generated/proto/proto-xxx.proto ...
 
65536
65536
65536
22656

 pbjs OK Converted 1 source files to json (816819 bytes, 125 ms)

End
Exit: 0

If I simply use child_process.spawnSync and use the pbjs file output option rather than reading from stdin, the correct output is produced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    child_processIssues and PRs related to the child_process subsystem.questionIssues that look for answers.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions