-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
buffer: runtime-deprecate Buffer constructor #7152
Conversation
@seishun I don't think this is viable at the moment. New API hasn't been backported even to 4.x afaik. There should be a single way to allocate Buffers on all supported node versions, so I hope that:
Perhaps target for 8.0 and re-evaluate later? |
Btw, this should also probably hard-deprecate |
Yeah, this is something that's going to need to wait for a while... I'm thinking at least v8 but likely longer. |
I'm thinking V10+ at minimum. Usage of this is very widespread. We should evaluate as time goes on. |
It's unlikely to decrease substantially without hard-deprecation. The whole point of hard-deprecation is to decrease the existing usage. I think there might be a misunderstanding here. I would like to remind that hard-deprecation means a one-time console notification that can be disabled. |
@seishun At this point, users are not migrating to the new Buffer API not because they didn't get a deprecation message in every app, but because the new API isn't supported by our current LTS version (and the Maintenance versions). |
@ChALkeR It's both. I'm not arguing against the lack-of-support-in-LTS factor. |
@Fishrock123 I still hope to see users migrating before v8.0 release. If the new API will be backported to v4, then I plan to file issues to most used repos starting from 2017-01, when 0.12 will become not supported anymore. So hopefully by April 2017 the usage of old API will decrease, and we should at least re-evaluate the deprecation before v8.0 release. |
To be clear: I am not saying that we should definitely force this in v8.0, but we should postpone this at least until v8.0 (unless the new API will get backported to 0.10/0.12, which I find unlikely). So, perhaps set a milestone to v8.0 to not forget to reevaluate by then? |
This can never happen. |
@trevnorris I don't follow. Either way, I don't see how hard-deprecating the constructor is incompatible with the constructor living on forever. |
@seishun For some of the methods of Uint8Array that return typed arrays again, the > a = Buffer.alloc(4)
<Buffer 00 00 00 00>
> a.map === Uint8Array.prototype.map
true
> a.map(x => x+1)
<Buffer 01 01 01 01> // Not a Uint8Array! .map() called a.constructor, which is Buffer. This is probably fixable by setting |
@addaleax @trevnorris |
I'm hoping to avoid that all together by making the Buffer constructor work correctly with EDIT: so that basically any inherited methods will return a Buffer instance. e.g. |
@trevnorris A couple of us chatted in IRC for a bit, and one of the problems would be that $ node --harmony-species -p 'Buffer[Symbol.species] === Buffer'
true So my comment above was not actually very meaningful. |
Just 0.12, isn't it? Since support for 0.10 ends in October. |
Ah, yes. 0.10 EOL is at the same time when 7.0 is going to be released. But I really doubt that it would be feasible to backport to 0.12 which ends in December. |
After some IRC discussion, it seems there is some agreement that the buffer shim would be sufficient for module authors who want to support old Node.js versions. So perhaps there might be no need to delay this by another 6 months. Also, I've found a way to hard-deprecate the Buffer constructor without affecting Uint8Array methods that doesn't depend on I've also updated the OP with another reason for hard-deprecation - namely, that it's a necessary step before Buffer can become a proper class that users can extend. |
Actually, on a second thought I'm fine with that, but I still want this backported to v4. I will make a PR for that to start the discussion.
See https://gist.github.com/ChALkeR/41cd82a8f3b8822860c77116e880d3c1. |
@@ -94,17 +99,19 @@ function alignPool() { | |||
} | |||
} | |||
|
|||
const bufferDeprecationWarning = | |||
deprecate(() => {}, 'Buffer constructor is deprecated. ' + | |||
'Use Buffer.from, Buffer.allocUnsafe or Buffer.alloc instead.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer the order here to be Buffer.from, Buffer.alloc or Buffer.allocUnsafe
instead, because the latter should be used only when people are better aware of what they are doing, i.e. are sure that they don't leak the resulted Buffer in an (even partially) unitialized state in any code branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just copied from the comment below, but I don't mind changing the order.
Well, I just ran |
@seishun I'm not sure if relying on the tests is sufficient here, it looks like they don't calculate the coverage. Not sure if that code is actually used somewhere, though. The file in question is https://github.com/mongodb/js-bson/blob/master/alternate_parsers/faster_bson.js#L369, and it looks like it's only used by some benchmark in that repo. I couldn't find any mentions of |
Now that #7562 has landed, what's the current status of this? |
This isn't about supporting 0.10 or older versions of 4 - a choice that should be completely up to the module authors btw. This is about deprecating a substantial amount of modules on npm and basically showing that Node core doesn't take backwards compatibility seriously. This isn't a change that should be postponed to v10. This is a change that should never happen and core should acknowledge that. |
@mafintosh, everyone, I have counterarguments to that, but they are not going to fit inside a comment. I am preparing a longer explanation, and it's going to be ready in a few days. I believe that we could continue this conversation then. |
This should never land. The primary focus for core should be stability above all else. This was part of the Node ethos which has been lost since the end of the Great Node/io.js Schism. Because of several changes in Node core, I have been forced to spend many hours needlessly updating packages and code which I should not have to be updating, simply because someone wanted core to use some (and in almost all cases, unnecessary) ES2015+ feature. The current predominant attitude by many contributing to Node core seems to be that breaking things is fine as long as tagged with a semver major. That is an okay attitude for userland packages, but not in the platform itself. What I, as a package author, want more than anything else is stability. Period. In a way, semver has become weaponized, a cudgel used to "force users to update". I have seen this happen repeatedly in Node core and as embodied by this PR. And frankly, because of the focus on supposed "innovation" and updating core with the "latest" and "greatest", I have lost trust in core, as I cannot trust that Node will provide a stable API. As a result, I try to avoid using core functionality and, where possible, would rather just write my own implementation over which I have full control. And if Node core development keeps going down the "breaking stuff is fine" path, I foresee a future where many people will adopt a similar attitude to myself and avoid core altogether. I cannot see how Node can perceive this as desirable. In short, if you want the ability to subclass, create a new API. Stability is not something which should be flippantly discarded. |
Hah, no. Stability wasn't an overriding concern until node was already several years old. We didn't get serious about that until v0.8/v0.10. I get that you feel stability should come first but you are committing the cardinal sin of rewriting history to fit your narrative. |
Let me try again to make the status of this PR clear: There is no consensus to land this PR at the current time. The CTC discussed the matter several months ago now and decided that a runtime deprecation of the That said, we are not closing the PR because there is a possibility that we might decide to go down this route. Why would we do so? The only reason why would intentionally break the Understand that those of us on the CTC are also Node.js users. These kinds of breaking changes affect us also. We are not keen on breaking our own code, much of which depends directly on modules that would be directly impacted by these changes. We do not make decisions to break APIs lightly. |
fwiw I still think this should be a goal in the long run |
I would like to ask everyone who has commented here to move the discussion to #9531, if only so the public discussion can take in a central place and not over multiple GH threads at once. |
@nodejs/ctc ... should we keep this open? I'm pretty sure the discussion has run it's course here. |
const bindingObj = {}; | ||
const internalUtil = require('internal/util'); | ||
|
||
class FastBuffer extends Uint8Array {} | ||
const FastBuffer = (() => class Buffer extends Uint8Array {})(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ChALkeR it was necessary because the FastBuffer.prototype.constructor = Buffer;
line was removed. It was removed to prevent Uint8Array methods (which call the constructor) from being affected by the deprecation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, here is the testcase: Buffer.alloc(10).map(x => x + 1)
(just for future reference).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/cc @jasnell
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd been trying to remember where I had seen this :-)
This was mostly superseded by #11968, and there is no concrete path forward runtime-deprecating it without a flag atm, and probably in another half a year. Perhaps it's time to close this and revisit later, probably in another PR. /ping @jasnell — could you confirm? @seishun thanks on the work here! It was important, and helped to reach the current state of runtime-deprecated-under-a-flag state of things. |
Yeah, I think this should just be closed at this point. We can revisit it later. |
Checklist
Affected core subsystem(s)
buffer
Description of change
new
) make it impossible, while other parts (such as construction from a string) make it more complex. It will make things much simpler if the problematic deprecated parts are removed. But they need to be runtime-deprecated first.