-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Implement Readable instead of Stream #740
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
Conversation
@@ -749,6 +749,7 @@ describe('Canvas', function () { | |||
it('Canvas#createSyncPNGStream()', function (done) { | |||
var canvas = new Canvas(20, 20); | |||
var stream = canvas.createSyncPNGStream(); | |||
assert(stream instanceof require("stream").Readable); |
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.
Single quotes please :)
Awesome 🙌 I've wanted to do this myself for quite some time, I think that this looks very good. I think the point with "async" vs "sync" is that "sync" is being run on the main thread, although calling back to javascript land in chunks? Haven't looked at the code properly to say though. In my opinion we shouldn't have sync streams at all since that seems like a very weird concept. |
dbee175
to
871f010
Compare
Thanks!
|
@@ -749,26 +749,35 @@ describe('Canvas', function () { | |||
it('Canvas#createSyncPNGStream()', function (done) { | |||
var canvas = new Canvas(20, 20); | |||
var stream = canvas.createSyncPNGStream(); | |||
assert(stream instanceof require('stream').Readable); |
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.
Could you move the require
call to the top of the file? You could still do var Readable = require('stream').Readable
Hmm I don't have a problem with dropping 0.8 support, according to this tweet and conversation, almost no one is using 0.8 anymore. https://twitter.com/seldo/status/712386414902521861 It should be a major bump though. The problems on 0.10 is a bit disturbing. Would it be possible for us to delay the first |
Maybe the data event is causing the stream to synchronously drain before you get around to putting the end listener. |
I agree with @calvinmetcalf. In streams 2, if all the data is available in JS-land and a |
@calvinmetcalf and @mcollina that appears to be what's happening -- thanks. I was hoping to find documentation about this change between 0.10 and 0.12 just to confirm that I wasn't doing something wrong. I think this is the diff that caused the behavior change: Anyway, wrapping it in a |
From nodejs/node-v0.x-archive#5865 (comment)
Indeed. |
871f010
to
6e603f1
Compare
Passing in 0.10 and later. Undid the changes to Node 5 doesn't seem to need to be an allowed failure anymore, btw. |
process.nextTick(function(){ | ||
canvas[method](options.bufsize, options.quality, options.progressive, function(err, chunk){ | ||
if (err) { | ||
self.emit('error', err); |
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.
wrong indentation
6a0ebb7
to
76787e1
Compare
}); | ||
}); | ||
} | ||
}; |
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.
allocating read
here or in the prototype has few differences, apart from style. I prefer to use prototype
when dealing with a class an inheriting.
Regarding this block, I would consider removing the process.nextTick
call. Plus, I think it's possible to recycle (declare inside the constructor) the function passed to canvas[method]
.
The golden rule is "try not to allocate functions inside _read
, _write
or _transform
". That is usually a very hot path and all those function allocation will slow you down.
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.
From earlier, we must use process.nextTick
.
Sorry for not being more clear, or for still not understanding what you're saying, but this is not a hot path because it has the surrounding if
block that causes evaluation of the function expression exactly once, thus there is nothing to reuse. I think then the only difference is style, but please let me know if I'm missing something.
As far as size of npm/inherits vs util.inherits
, this is a node module only.
If you care about browser size, I suggest you using |
ac615b7
to
4cacbe8
Compare
Updated travis.yaml: remove node 0.8, add 6.x and no longer allow 5.x to fail. CI green! |
4cacbe8
to
dc706ec
Compare
(Needs update since PDF stream was added) |
@zbjornson sorry for the delay on this, I've now cut a 1.x branch from master and from now on master is for Canvas 2.x. I'm dropping 0.8 support in #825 so this should be good to merge 👍 |
No problemo, will fix conflicts and add PDF stream this week. :) |
f288b05
to
fb84653
Compare
@LinusU updated :) |
I do think the comments by @mcollina deserve another look, can |
fb84653
to
8b5dc05
Compare
If 0.10 is dropped, I had
The 4th option (reassign to noop) is the best of both worlds -- no internal properties exposed and fast construction. Updated PR to use that method. |
@LinusU gentle nudge, from my side this is ready for merge into 2.0. :) |
Sorry for the delay, I hope to get some time this week 👍 |
Sorry for the delay, awesome work! |
TODO at myself (or anyone else who wants to do it): since 0.10 is dropped now, the nextTick stuff can be removed, per discussion above. |
See discussion in Automattic#740
See discussion in Automattic#740
Would benefit from some testers (@mitar?) and feedback...
Both JPEGStream and PNGStream currently inherit from
stream.Stream
, notstream.Readable
. As a consequence, they are missing a bunch of methods. (See #674, #232.) They will also start flowing without a listener, but because the stream is wrapped inprocess.nextTick
I think that would only be noticed from the node prompt.It was straightforward to switch to
Readable
. I didn't attempt to make the C++ code wait to queue more data after the stream starts (first call to.read
); after the first chunk it pushes data into the stream queue without waiting for the stream consumer to call.read
(directly or indirectly). There should be no lost bytes as a result of flowing without a sink anymore, but consumers could see more memory consumption from the queuing of bytes that previously would have been lost into the ether.I'm still confused about the "async" vs "sync" names of these APIs -- they all emit chunks of data within callbacks, which seems async to the consumer, if not internally.