Skip to content

Writable#end does not trigger 'finish' event: why? #2112

@fbiville

Description

@fbiville
  • Node.js Version: v12.8.0
  • OS: Mac OS Mojave (10.14.6)
  • Scope (install, code, runtime, meta, other?): runtime
  • Module (and version) (if relevant): stream

Quoting the stream documentation:

The 'finish' event is emitted after the stream.end() method has been called, and all data has been flushed to the underlying system.

In the setup explained below, it seems that the 'finish' is not triggered or received despite calling end on the stream.

I have the following Write "pipeline" stream, whose main responsibility is to dispatch data to the appropriate Transform "input" stream among the n available. These n Transform all write to a destination stream.

The "pipeline" stream is implemented as follows (and hardcoded to 3 "input" streams here to keep things concise):

class Pipeline extends Writable {
    constructor(options, destinationStream) {
        super(options);
        this.destinationStream = destinationStream;
        this.inputStreams = [
            new InputTransform(options),
            new InputTransform(options),
            new InputTransform(options)
        ];
        this.inputStreams.forEach((it) => {
            it.on('error', (err) => {
                this.emit('error', err);
            });
            it.pipe(this.destinationStream);
        });
        this.on('finish', () => {
            this.inputStreams.forEach((it) => it.emit('end'));
        });
        this.on('error', () => {
            this.end();
        })
    }

    _write(chunk, _, callback) {
        this.inputStreams[chunk['index']].write(chunk['data']);
    }
}

You can see that the "pipeline" intercepts errors coming from any of the "input" streams and emits the intercepted error itself.
When an 'error' event occurs, the "pipeline" ends itself and I expect that the pipeline receives a "finish" event afterwards to end all the "input" streams.

However, as you see if you clone and run this experiment, the 'finish' event is never triggered or never received.

What is going on?

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