@isaac

Thanks for the detailed reply.

Your proposed API is optimal for the sync case (memory stream). I handle 
this case with a trampoline (streamline) or a nextTick call (pure JS), 
which introduces a bit of overhead.

I still prefer the callback style over the event style because a read() 
that returns null is always followed by either a "readable" or an "error" 
event so the follow up event is fully correlated with the read() call. But 
anyway, this API design is your call and the new API is clearly heading in 
the right direction. I'll keep my "correlation" ramblings for a future blog 
post.

Bruno

On Monday, July 30, 2012 7:02:12 PM UTC+2, Isaac Schlueter wrote:
>
> > there is another thing this would break, it would be impossible to 
> > stream a .read() based ReadableStream to multiple destinations... 
>
> Yeah, that use case is going to be hard.  If you want a tee-stream, 
> you can implement it pretty easily on top of this.  And of course, if 
> you use the "data" event facade, then it'll keep working just how it 
> does, so I don't expect existing programs to be affected too badly 
> until they specifically try to upgrade. 
>
> But, yes, this is a thing that's going to break in 0.9, most likely, 
> and someone probably will be affected by it.  The best approach is to 
> do it as soon as possible and document the changes. 
>
> On Sun, Jul 29, 2012 at 10:51 AM, Bruno Jouhier <[email protected]> 
> wrote: 
> > Given this, I probably favor the callback style a lot more than most 
> node 
> > developers. 
>
> For several implementations, a read(n, cb) method is easier to do. 
> For example, on Windows, that's how we read from sockets, and on all 
> platforms, that's how fs.read works.  So, we *must* implement 
> something like this for fs read streams anyway, and if we want elegant 
> cross-platform support, then we'll have to do that for TCP and Pipes 
> as well. 
>
> The ReadableStream base class will have a read([n]) method that 
> returns either up-to-n bytes (or some arbitrary number of bytes if n 
> is unspecified), or null.  If it returns null, then you wait for a 
> 'readable' event and try again. 
>
> It will also have a _read(n, function(er, bytes)) method that you can 
> override with your own implementation details.  The assumption here is 
> that: n is always specified, the cb is called at some point in the 
> future with an error or up-to-n bytes.  The ReadableStream class will 
> take care of managing the buffer and calling this._read when 
> appropriate.  If there are no more bytes to read, then _read(n, cb) 
> should call the cb with null. 
>
> This makes it easy to interface with underlying systems that can only 
> do asynchronous reads, while still getting the benefits of the simpler 
> read(n)/emit('readable') API. 
>
> Of course, if your system CAN safely do reads synchronously (ie, if 
> it's some kind of abstract stream that reads from memory and doesn't 
> have to do any slow IO) then you can just override the read(n) method 
> instead of the _read(n, cb) method. 
>

Reply via email to