Skip to content

Deprecating req.flush() has caused other problems #2920

@patrick-steele-idem

Description

@patrick-steele-idem

tldr; Implementing req.flush() and having it log a deprecation message to the console is causing problems with code that expects flush() to be implemented correctly.

I understand that OutgoingMessage used to have a flush() method that was poorly named. This was later fixed by renaming it to flushHeaders(). However, instead of stopping there, a stub for the flush() method was put in with the following implementation:

OutgoingMessage.prototype.flush = util.deprecate(function() {
    this.flushHeaders();
}, 'flush is deprecated. Use flushHeaders instead.');

See commit: b2e00e3

I understand that this was done to maintain backwards compatibility, but it is also preventing libraries from actually using the flush() method for the correct purpose. It's my opinion that we should have just deleted the old flush() method (it was a major release after all), but it's a little late for that now....

This change is causing a problem for libraries that check if flush() is implemented and want to use it for the purpose of actually flushing buffered data. You are probably thinking that flush() was never used for that purpose, but that is not true...For example, the compression module monkey patches the response stream to include a flush() method for the expected and correct purpose. See:

https://github.com/expressjs/compression/blob/c2af8bd8d5cec3577b40d61859ca3a0467052ded/index.js#L61-L65

The marko templating engine is an asynchronous and streaming templating engine that is designed to flush() bytes to the underlying stream whenever an asynchronous fragment is completed. It works by conditionally checking if the underlying stream has a flush() method and it will then call the flush() method if found. See:

https://github.com/marko-js/async-writer/blob/5ef039139041fb40aadcdc0b7a10eb7d3d3a48b5/lib/AsyncWriter.js#L494-L496

This works great when using the gzip compression middleware that monkey patches the flush() method but when rendering to an OutgoingMessage stream with the compression middleware we are seeing a deprecation message being written to the console 😞

As a result, users of marko are reporting the problem that a deprecation warning is being written to the console: marko-js-archive/async-writer#3

I understand the dilemma, but without knowing if a stream is really flushable we are seeing problems when trying to use the flush() method for the purpose that the compression middleware intended.

I don't know the right answer here, but just wanted to start the discussion to see how soon we can fix this inconsistency (Node.js 5.0? If so, how long will that be?) and to make more people aware of the issue. Is there a lot of code in the wild that was using flush() for the purpose of flushing headers on an OutgoingMessage?

Metadata

Metadata

Assignees

No one assigned

    Labels

    httpIssues or PRs related to the http 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