Re: Thoughts behind the Streams API ED

2013-11-12 Thread Aymeric Vitte

Takeshi,

See discussion here too: https://github.com/whatwg/streams/issues/33

The problem with stop again is that I need to handle myself the clone 
operations, the advantage of stop-eof is:


- clone the operation
- close it
- restart from the clone

And as I mentioned before this would work for any operation that has 
unresolved bytes (TextDecoder, etc) without the need of modifying the 
operation API for explicit clones or options.


Regards

Aymeric


Le 08/11/2013 14:31, Takeshi Yoshino a e'crit :
On Fri, Nov 8, 2013 at 8:54 PM, Aymeric Vitte vitteayme...@gmail.com 
mailto:vitteayme...@gmail.com wrote:


I would expect Poc (stop, keep 0xd1 for the next data) and сия

It can be seen a bit different indeed, while with crypto you
expect the finalization of the operation since the begining (but
only by computing the latest bytes), here you can not expect the
string since the begining of course.

It just depends how the Operation (here TextDecoder) handles
stop but I find it very similar, TextEncoder closes the operation
with the bytes it has and clone its state (ie do nothing here
except clearing resolved bytes and keeping unresolved ones for
data to come).


I'd say more generally that stop() is kinda in-band control signal 
that is inserted between elements of the stream and distinguishable 
from the elements. As you said, interpretation of the stop() symbol 
depends on what the destination is.


One thing I'm still not sure is that I think you can just add stop() 
equivalent method to the destination, and

- pipe() data until the point you were calling stop()
- call the stop() equivalent on e.g. hash
- restart pipe()

At least our spec allows for this. Of course, it's convenient that 
Stream can carry such a signal. But there's trade-off between the 
convenience and API size. Similar to decision whether we include 
abort() to WritableByteStream or not.


Extremely, abort(), close() and stop() can be merged into one method 
(unless abort() method has a functionality to abandon already written 
data). They're all signal inserting methods.


close() - signal(FIN)
stop(info) - signal(CONTROL, info)
abort(error) - signal(ABORT, error)

and the signal is packed and inserted into the stream's internal buffer.


--
Peersm : http://www.peersm.com
node-Tor : https://www.github.com/Ayms/node-Tor
GitHub : https://www.github.com/Ayms



Re: Thoughts behind the Streams API ED

2013-11-12 Thread Aymeric Vitte
No, see my previous reply, unless I am proven incorrect, I still think 
we should have:


- pause/unpause
- stop/(implicit resume)

Regards,

Aymeric

Le 11/11/2013 22:06, Takeshi Yoshino a écrit :

Aymeric,

Re: pause()/resume(),

I've moved flow control functionality for non-exact read() method to a 
separate attribute pullAmount [1] [2]. pullAmount limits the max size 
of data to be read by read() method. Currently the pipe() method is 
specified not to respect pullAmount but we can choose to have it to 
respect pullAmount, i.e. pausing pipe()'s transfer when pullAmount is 
set to 0. Does this work for your use case?


[1] https://www.w3.org/Bugs/Public/show_bug.cgi?id=23790
[2] https://dvcs.w3.org/hg/streams-api/rev/8a7f99536516


--
Peersm : http://www.peersm.com
node-Tor : https://www.github.com/Ayms/node-Tor
GitHub : https://www.github.com/Ayms



Re: Thoughts behind the Streams API ED

2013-11-12 Thread Takeshi Yoshino
On Tue, Nov 12, 2013 at 5:23 PM, Aymeric Vitte vitteayme...@gmail.comwrote:

  No, see my previous reply, unless I am proven incorrect, I still think we
 should have:

 - pause/unpause
 - stop/(implicit resume)

 Regards,

 Aymeric

 Le 11/11/2013 22:06, Takeshi Yoshino a écrit :

  Aymeric,

  Re: pause()/resume(),


Sorry. This is typo. I meant pause()/unpause().



  I've moved flow control functionality for non-exact read() method to a
 separate attribute pullAmount [1] [2]. pullAmount limits the max size of
 data to be read by read() method. Currently the pipe() method is specified
 not to respect pullAmount but we can choose to have it to respect
 pullAmount, i.e. pausing pipe()'s transfer when pullAmount is set to 0.
 Does this work for your use case?

  [1] https://www.w3.org/Bugs/Public/show_bug.cgi?id=23790
 [2] https://dvcs.w3.org/hg/streams-api/rev/8a7f99536516


 --
 Peersm : http://www.peersm.com
 node-Tor : https://www.github.com/Ayms/node-Tor
 GitHub : https://www.github.com/Ayms




Re: Thoughts behind the Streams API ED

2013-11-12 Thread Takeshi Yoshino
On Tue, Nov 12, 2013 at 5:20 PM, Aymeric Vitte vitteayme...@gmail.comwrote:

  Takeshi,

 See discussion here too: https://github.com/whatwg/streams/issues/33

 The problem with stop again is that I need to handle myself the clone
 operations, the advantage of stop-eof is:

 - clone the operation
 - close it
 - restart from the clone

 And as I mentioned before this would work for any operation that has
 unresolved bytes (TextDecoder, etc) without the need of modifying the
 operation API for explicit clones or options.


OK. I understood your needs.

As explained in the previous mail, if we decide to take in your suggestion,
I'd implement your stop-eof as a more generic in-band control signal. In
other words, changing the draft to propose message stream than byte stream.

I estimate that this feature sophisticates implementation much. So, I want
to hear more support and justification.

For now, I filed a bug to track discussion.
https://www.w3.org/Bugs/Public/show_bug.cgi?id=23799


Re: Thoughts behind the Streams API ED

2013-11-11 Thread Takeshi Yoshino
Aymeric,

Re: pause()/resume(),

I've moved flow control functionality for non-exact read() method to a
separate attribute pullAmount [1] [2]. pullAmount limits the max size of
data to be read by read() method. Currently the pipe() method is specified
not to respect pullAmount but we can choose to have it to respect
pullAmount, i.e. pausing pipe()'s transfer when pullAmount is set to 0.
Does this work for your use case?

[1] https://www.w3.org/Bugs/Public/show_bug.cgi?id=23790
[2] https://dvcs.w3.org/hg/streams-api/rev/8a7f99536516


Re: Thoughts behind the Streams API ED

2013-11-08 Thread Aymeric Vitte
Please see here https://github.com/whatwg/streams/issues/33, I realized 
that this would apply to operations like textDecoder too without the 
need of an explicit stream option, so that's no more WebCrypto only related.


Regards

Aymeric

Le 07/11/2013 11:25, Aymeric Vitte a écrit :


Le 07/11/2013 10:42, Takeshi Yoshino a écrit :
On Thu, Nov 7, 2013 at 6:27 PM, Aymeric Vitte vitteayme...@gmail.com 
mailto:vitteayme...@gmail.com wrote:



Le 07/11/2013 10:21, Takeshi Yoshino a écrit :

On Thu, Nov 7, 2013 at 6:05 PM, Aymeric Vitte
vitteayme...@gmail.com mailto:vitteayme...@gmail.com wrote:

stop/resume:

Indeed as I mentioned this is related to WebCrypto Issue22
but I don't think this is a unique case. Issue22 was closed
because of lack of proposals to solve it, apparently I was
the only one to care about it (but I saw recently some other
messages that seem to be related), and finally this would
involve a public clone method with associated security concerns.

But with Streams it could be different, the application will
internally clone the state of the operation probably
eliminating the security issues, as simple as that.

To describe simply the use case, let's take a progressive
hash computing 4 bytes by 4 bytes:

incoming stream: ABCDE bytes
hash operation: process ABCD, keep E for the next computation
incoming stream: FGHI bytes + STOP-EOF
hash operation: process EFGH, process STOP-EOF: clone the
state of the hash, close the operation: digest hash with I


So, here, partial hash for ABCDEFGH is output


No, you get the digest for ABCDEFGHI and you get a cloned
operation which will restart from ABCDEFGH



OK.



resume:
incoming stream: JKLF
hash operation (clone): process IJKL, keep F for next
computation
etc...


and if we close the stream here we'll get a hash for
ABCDEFGHIJKLFPPP (P is padding). Right?


If you close the stream here you get the digest for ABCDEFGHIJKLF


resume happens implicitly when new data comes in without explicit 
method call say resume()?


Good question, I would say yes, so we don't need resume finally, but 
maybe others have different opinion, let's ask whatwg if they foresee 
this case.





So you do not restart the operation as if it was the first
time it was receiving data, you just continue it from the
state it was when stop was received.

That's not so unusual to do this, it has been requested many
times in node.



-- 
Peersm :http://www.peersm.com

node-Tor :https://www.github.com/Ayms/node-Tor
GitHub :https://www.github.com/Ayms




--
Peersm :http://www.peersm.com
node-Tor :https://www.github.com/Ayms/node-Tor
GitHub :https://www.github.com/Ayms


--
Peersm : http://www.peersm.com
node-Tor : https://www.github.com/Ayms/node-Tor
GitHub : https://www.github.com/Ayms



Re: Thoughts behind the Streams API ED

2013-11-08 Thread Takeshi Yoshino
On Fri, Nov 8, 2013 at 5:38 PM, Aymeric Vitte vitteayme...@gmail.comwrote:

  Please see here https://github.com/whatwg/streams/issues/33, I realized
 that this would apply to operations like textDecoder too without the need
 of an explicit stream option, so that's no more WebCrypto only related.


Similar but a bit different?

For clarification, could you review the following?

textDecoderStream.write(araybuffer of 0xd0 0xa0 0xd0 0xbe 0xd1);
textDecoderStream.stop();
textDecoderStream.write(arraybuffer of 0x81 0xd1 0x81 0xd0 0xb8 0xd1 0x8f)

This generates DOMString stream [Рос, сия]. Right? Or you want to get
[Рос, Россия]?


Re: Thoughts behind the Streams API ED

2013-11-08 Thread Takeshi Yoshino
Sorry. I've cut the input at wrong position.

textDecoderStream.write(arraybuffer of 0xd0 0xa0 0xd0 0xbe 0xd1 0x81 0xd1);
textDecoderStream.stop();
textDecoderStream.write(arraybuffer of 0x81 0xd0 0xb8 0xd1 0x8f)


Re: Thoughts behind the Streams API ED

2013-11-08 Thread Aymeric Vitte

I would expect Poc (stop, keep 0xd1 for the next data) and сия

It can be seen a bit different indeed, while with crypto you expect the 
finalization of the operation since the begining (but only by computing 
the latest bytes), here you can not expect the string since the begining 
of course.


It just depends how the Operation (here TextDecoder) handles stop but 
I find it very similar, TextEncoder closes the operation with the bytes 
it has and clone its state (ie do nothing here except clearing 
resolved bytes and keeping unresolved ones for data to come).


Regards

Aymeric

Le 08/11/2013 11:33, Takeshi Yoshino a écrit :

Sorry. I've cut the input at wrong position.

textDecoderStream.write(arraybuffer of 0xd0 0xa0 0xd0 0xbe 0xd1 0x81 
0xd1);

textDecoderStream.stop();
textDecoderStream.write(arraybuffer of 0x81 0xd0 0xb8 0xd1 0x8f)


--
Peersm : http://www.peersm.com
node-Tor : https://www.github.com/Ayms/node-Tor
GitHub : https://www.github.com/Ayms




Re: Thoughts behind the Streams API ED

2013-11-08 Thread Takeshi Yoshino
On Fri, Nov 8, 2013 at 8:54 PM, Aymeric Vitte vitteayme...@gmail.comwrote:

 I would expect Poc (stop, keep 0xd1 for the next data) and сия

 It can be seen a bit different indeed, while with crypto you expect the
 finalization of the operation since the begining (but only by computing the
 latest bytes), here you can not expect the string since the begining of
 course.

 It just depends how the Operation (here TextDecoder) handles stop but I
 find it very similar, TextEncoder closes the operation with the bytes it
 has and clone its state (ie do nothing here except clearing resolved
 bytes and keeping unresolved ones for data to come).


I'd say more generally that stop() is kinda in-band control signal that is
inserted between elements of the stream and distinguishable from the
elements. As you said, interpretation of the stop() symbol depends on what
the destination is.

One thing I'm still not sure is that I think you can just add stop()
equivalent method to the destination, and
- pipe() data until the point you were calling stop()
- call the stop() equivalent on e.g. hash
- restart pipe()

At least our spec allows for this. Of course, it's convenient that Stream
can carry such a signal. But there's trade-off between the convenience and
API size. Similar to decision whether we include abort() to
WritableByteStream or not.

Extremely, abort(), close() and stop() can be merged into one method
(unless abort() method has a functionality to abandon already written
data). They're all signal inserting methods.

close() - signal(FIN)
stop(info) - signal(CONTROL, info)
abort(error) - signal(ABORT, error)

and the signal is packed and inserted into the stream's internal buffer.


Re: Thoughts behind the Streams API ED

2013-11-07 Thread Aymeric Vitte

stop/resume:

Indeed as I mentioned this is related to WebCrypto Issue22 but I don't 
think this is a unique case. Issue22 was closed because of lack of 
proposals to solve it, apparently I was the only one to care about it 
(but I saw recently some other messages that seem to be related), and 
finally this would involve a public clone method with associated 
security concerns.


But with Streams it could be different, the application will internally 
clone the state of the operation probably eliminating the security 
issues, as simple as that.


To describe simply the use case, let's take a progressive hash computing 
4 bytes by 4 bytes:


incoming stream: ABCDE bytes
hash operation: process ABCD, keep E for the next computation
incoming stream: FGHI bytes + STOP-EOF
hash operation: process EFGH, process STOP-EOF: clone the state of the 
hash, close the operation: digest hash with I


resume:
incoming stream: JKLF
hash operation (clone): process IJKL, keep F for next computation
etc...

So you do not restart the operation as if it was the first time it was 
receiving data, you just continue it from the state it was when stop was 
received.


That's not so unusual to do this, it has been requested many times in node.

pipe/fork: I think b is better.

Regards

Aymeric



Le 06/11/2013 20:15, Takeshi Yoshino a écrit :
On Wed, Nov 6, 2013 at 7:33 PM, Aymeric Vitte vitteayme...@gmail.com 
mailto:vitteayme...@gmail.com wrote:


I have seen the different bugs too, some comments:

- maybe I have missed some explaination or some obvious thing but
I don't understand very well right now the difference/use between
readable/writablebytestream and bytestream


ReadableByteStream and WritableByteStream are defining interfaces not 
only for ByteStream but more generally for other APIs. For example, we 
discussed how WebCrypto's encryption method should work with Stream 
concept recently, and one idea you showed was making WebCrypto.subtle 
return an object (which I called filter) to which we can pipe data. 
By defining a protocol how to pass data to consumer as the 
WritableByteStream interface, we can reuse it later for defining IDL 
for those filters. Similarly, ReadableByteStream can provide uniform 
protocol how data producing APIs should communicate with consumers.


ByteStream is now a class inheriting both ReadableByteStream and 
WritableByteStream (sorry, I forgot to include inheritance info in the 
IDL).


- pause/unpause: as far as I understand the whatwg spec does not
recommend it but I don't understand the reasons. As I previously
mentionned the idea is to INSERT a pause signal in the stream, you
can not control the stream and therefore know when you are pausing it.


Maybe after decoupling the interface, pause/unpause are things to be 
added to ByteStream? IIUC, pause prevents data from being read from a 
ByteStream, and unpause removes the dam?


- stop/resume: same, see my previous post, the difference is that
the consuming API should clone the state of the operation and
close the current operation as if eof was received, then restart
from the clone on resume


Sorry that I haven't replied to your one.

Your post about those methods: 
http://lists.w3.org/Archives/Public/public-webapps/2013OctDec/0343.html

WebCrypto ISSUE-22: http://www.w3.org/2012/webcrypto/track/issues/22

Maybe I still don't quite understand your ideas. Let me confirm.

stop() tells the consumer API implementing WritableByteStream that it 
should behave as if it received EOF, but when resume() is called, 
restart processing the data written between stop() call and resume() 
call as if the API received data for the first time?


How should stop() work for ByteStream? ByteStream's read() method will 
receive EOF at least once when all data written before stop() call has 
been read, and it keeps returning EOF until resume() tells the 
ByteStream to restart outputting?


I've been feeling that your use case is very specific to WebCrypto. 
Saving state and restoring it sounds more like feature request for 
WebCrypto, not a Stream.


But I'm a bit interested in what your stop()/resume() enables. With 
this feature, ByteStream becomes message stream which is convenient 
for handling WebSocket.


- pipe []/fork: I don't see why the fast stream should wait for
the slow one, so maybe the stream is forked and pause can be used
for the slow one


There could be apps that want to limit memory usage strictly. We think 
there're two strategies fork() can take.

a) wait until the slowest substream consumes
b) grow not to block the fastest substream while keeping data for the 
slowest


a) is useful to limit memory usage. b) is more performance oriented.


- flow control: could it be possible to advertise a maximum
bandwidth rate for a stream?


It's currently communicated as window similar to TCP. Consumer can 
adjust size argument of read() and frequency of read() call to match 
the 

Re: Thoughts behind the Streams API ED

2013-11-07 Thread Takeshi Yoshino
On Thu, Nov 7, 2013 at 6:05 PM, Aymeric Vitte vitteayme...@gmail.comwrote:

  stop/resume:

 Indeed as I mentioned this is related to WebCrypto Issue22 but I don't
 think this is a unique case. Issue22 was closed because of lack of
 proposals to solve it, apparently I was the only one to care about it (but
 I saw recently some other messages that seem to be related), and finally
 this would involve a public clone method with associated security concerns.

 But with Streams it could be different, the application will internally
 clone the state of the operation probably eliminating the security issues,
 as simple as that.

 To describe simply the use case, let's take a progressive hash computing 4
 bytes by 4 bytes:

 incoming stream: ABCDE bytes
 hash operation: process ABCD, keep E for the next computation
 incoming stream: FGHI bytes + STOP-EOF
 hash operation: process EFGH, process STOP-EOF: clone the state of the
 hash, close the operation: digest hash with I


So, here, partial hash for ABCDEFGH is output



 resume:
 incoming stream: JKLF
 hash operation (clone): process IJKL, keep F for next computation
 etc...


and if we close the stream here we'll get a hash for ABCDEFGHIJKLFPPP (P is
padding). Right?


  So you do not restart the operation as if it was the first time it was
 receiving data, you just continue it from the state it was when stop was
 received.

 That's not so unusual to do this, it has been requested many times in node.



Re: Thoughts behind the Streams API ED

2013-11-07 Thread Aymeric Vitte


Le 07/11/2013 10:21, Takeshi Yoshino a écrit :
On Thu, Nov 7, 2013 at 6:05 PM, Aymeric Vitte vitteayme...@gmail.com 
mailto:vitteayme...@gmail.com wrote:


stop/resume:

Indeed as I mentioned this is related to WebCrypto Issue22 but I
don't think this is a unique case. Issue22 was closed because of
lack of proposals to solve it, apparently I was the only one to
care about it (but I saw recently some other messages that seem to
be related), and finally this would involve a public clone method
with associated security concerns.

But with Streams it could be different, the application will
internally clone the state of the operation probably eliminating
the security issues, as simple as that.

To describe simply the use case, let's take a progressive hash
computing 4 bytes by 4 bytes:

incoming stream: ABCDE bytes
hash operation: process ABCD, keep E for the next computation
incoming stream: FGHI bytes + STOP-EOF
hash operation: process EFGH, process STOP-EOF: clone the state of
the hash, close the operation: digest hash with I


So, here, partial hash for ABCDEFGH is output


No, you get the digest for ABCDEFGHI and you get a cloned operation 
which will restart from ABCDEFGH




resume:
incoming stream: JKLF
hash operation (clone): process IJKL, keep F for next computation
etc...


and if we close the stream here we'll get a hash for ABCDEFGHIJKLFPPP 
(P is padding). Right?


If you close the stream here you get the digest for ABCDEFGHIJKLF


So you do not restart the operation as if it was the first time it
was receiving data, you just continue it from the state it was
when stop was received.

That's not so unusual to do this, it has been requested many times
in node.



--
Peersm : http://www.peersm.com
node-Tor : https://www.github.com/Ayms/node-Tor
GitHub : https://www.github.com/Ayms



Re: Thoughts behind the Streams API ED

2013-11-07 Thread Takeshi Yoshino
On Thu, Nov 7, 2013 at 6:27 PM, Aymeric Vitte vitteayme...@gmail.comwrote:


 Le 07/11/2013 10:21, Takeshi Yoshino a écrit :

  On Thu, Nov 7, 2013 at 6:05 PM, Aymeric Vitte vitteayme...@gmail.comwrote:

  stop/resume:

 Indeed as I mentioned this is related to WebCrypto Issue22 but I don't
 think this is a unique case. Issue22 was closed because of lack of
 proposals to solve it, apparently I was the only one to care about it (but
 I saw recently some other messages that seem to be related), and finally
 this would involve a public clone method with associated security concerns.

 But with Streams it could be different, the application will internally
 clone the state of the operation probably eliminating the security issues,
 as simple as that.

 To describe simply the use case, let's take a progressive hash computing
 4 bytes by 4 bytes:

 incoming stream: ABCDE bytes
 hash operation: process ABCD, keep E for the next computation
 incoming stream: FGHI bytes + STOP-EOF
 hash operation: process EFGH, process STOP-EOF: clone the state of the
 hash, close the operation: digest hash with I


  So, here, partial hash for ABCDEFGH is output


 No, you get the digest for ABCDEFGHI and you get a cloned operation which
 will restart from ABCDEFGH



OK.





 resume:
 incoming stream: JKLF
 hash operation (clone): process IJKL, keep F for next computation
 etc...


  and if we close the stream here we'll get a hash for ABCDEFGHIJKLFPPP (P
 is padding). Right?


 If you close the stream here you get the digest for ABCDEFGHIJKLF


resume happens implicitly when new data comes in without explicit method
call say resume()?





  So you do not restart the operation as if it was the first time it was
 receiving data, you just continue it from the state it was when stop was
 received.

 That's not so unusual to do this, it has been requested many times in
 node.


 --
 Peersm : http://www.peersm.com
 node-Tor : https://www.github.com/Ayms/node-Tor
 GitHub : https://www.github.com/Ayms




Re: Thoughts behind the Streams API ED

2013-11-07 Thread Aymeric Vitte


Le 07/11/2013 10:42, Takeshi Yoshino a écrit :
On Thu, Nov 7, 2013 at 6:27 PM, Aymeric Vitte vitteayme...@gmail.com 
mailto:vitteayme...@gmail.com wrote:



Le 07/11/2013 10:21, Takeshi Yoshino a écrit :

On Thu, Nov 7, 2013 at 6:05 PM, Aymeric Vitte
vitteayme...@gmail.com mailto:vitteayme...@gmail.com wrote:

stop/resume:

Indeed as I mentioned this is related to WebCrypto Issue22
but I don't think this is a unique case. Issue22 was closed
because of lack of proposals to solve it, apparently I was
the only one to care about it (but I saw recently some other
messages that seem to be related), and finally this would
involve a public clone method with associated security concerns.

But with Streams it could be different, the application will
internally clone the state of the operation probably
eliminating the security issues, as simple as that.

To describe simply the use case, let's take a progressive
hash computing 4 bytes by 4 bytes:

incoming stream: ABCDE bytes
hash operation: process ABCD, keep E for the next computation
incoming stream: FGHI bytes + STOP-EOF
hash operation: process EFGH, process STOP-EOF: clone the
state of the hash, close the operation: digest hash with I


So, here, partial hash for ABCDEFGH is output


No, you get the digest for ABCDEFGHI and you get a cloned
operation which will restart from ABCDEFGH



OK.



resume:
incoming stream: JKLF
hash operation (clone): process IJKL, keep F for next computation
etc...


and if we close the stream here we'll get a hash for
ABCDEFGHIJKLFPPP (P is padding). Right?


If you close the stream here you get the digest for ABCDEFGHIJKLF


resume happens implicitly when new data comes in without explicit 
method call say resume()?


Good question, I would say yes, so we don't need resume finally, but 
maybe others have different opinion, let's ask whatwg if they foresee 
this case.





So you do not restart the operation as if it was the first
time it was receiving data, you just continue it from the
state it was when stop was received.

That's not so unusual to do this, it has been requested many
times in node.



-- 
Peersm :http://www.peersm.com

node-Tor :https://www.github.com/Ayms/node-Tor
GitHub :https://www.github.com/Ayms




--
Peersm : http://www.peersm.com
node-Tor : https://www.github.com/Ayms/node-Tor
GitHub : https://www.github.com/Ayms



Re: Thoughts behind the Streams API ED

2013-11-06 Thread Aymeric Vitte

I have seen the different bugs too, some comments:

- maybe I have missed some explaination or some obvious thing but I 
don't understand very well right now the difference/use between 
readable/writablebytestream and bytestream


- pause/unpause: as far as I understand the whatwg spec does not 
recommend it but I don't understand the reasons. As I previously 
mentionned the idea is to INSERT a pause signal in the stream, you can 
not control the stream and therefore know when you are pausing it.


- stop/resume: same, see my previous post, the difference is that the 
consuming API should clone the state of the operation and close the 
current operation as if eof was received, then restart from the clone on 
resume


- pipe []/fork: I don't see why the fast stream should wait for the slow 
one, so maybe the stream is forked and pause can be used for the slow one


- flow control: could it be possible to advertise a maximum bandwidth 
rate for a stream?


Regards

Aymeric

Le 04/11/2013 18:11, Takeshi Yoshino a écrit :
I'd like to summarize my ideas behind this API surface since the 
overlap thread is too long. We'll put these into bug entries soon.


Feedback on Overlap thread, especially Issac's exhaustive list of 
considerations and conversation with Aymeric were very helpful. In 
reply to his mail, I drafted my initial proposal [2] in past which 
addresses almost all of them. Since the API surface was so big, I 
tried to compact it while incorporating Promises. Current ED [3] 
addresses not all but some of important requirements. I think it's a 
good (re)starting point.


* Flow control
read() and write() in the ED does provide flow control by controlling 
the timing of resolution of the returned Promise. A Stream would have 
a window to limit data to be buffered in it. If a big value is passed 
as size parameter of read(), it may extend the window if necessary.


In reading data as a DOMString, the size param of read() doesn't 
specify exact raw size of data to be read out. It just works as 
throttle to prevent internal buffer from being drained too fast. 
StreamReadResult tells how many bytes were actually consumed.


If more explicit and precise flow control is necessary, we could 
cherry pick some from my old big API proposal [1]. For example, making 
window size configurable.


If it makes sense, size can be generalized to be cost of each element. 
It would be useful when trying to generalize Stream to various objects.


To make window dynamically adjustable, we could introduce methods such 
as drainCapacity(), expandCapacity() to it.


* Passive producer
Thinking of producers like a random number generator, it's not always 
good to ask a producer to prepare data and push it to a Stream using 
write(). This was possible in [2], but not in the ED. This can be 
addressed for example by adding one overload to write().
- write() and write(size) doesn't write data but wait until the Stream 
can accept some amount or the specified size of data.


* Conversion from existing active and unstoppable producer API
E.g. WebSocket invokes onmessage immediately when new data is 
available. For this kind of API, finite size Stream cannot absorb the 
production. So, there'll be need to buffer read data manually. In [2], 
Stream always accepted write() even if buffer is full assuming that if 
necessary the producer should be using onwritable method.


Currently, only one write() can be issued concurrently, but we can 
choose to have Stream queue write() requests in it.


* Sync read if possible
By adding sync flag to StreamReadResult and introducing 
StreamWriteResult to signal if read was done sync (data is the actual 
result) or async (data is a Promise) to save Promise post tasking cost.


I estimated that post tasking overhead should be negligible for bulk 
reading, and when to read small fields, we often read some amount into 
ArrayBuffer and then parse it directly. So it's currently excluded.


* Multiple consumers
pipe() can take multiple destination Streams. This allows for 
mirroring Stream's output into two or more Streams. I also considered 
making Stream itself consumable, but I thought it complicates API and 
implementation.

- Elements in internal buffer need to be reference counted.
- It must be able to distinguish consumers.

If one of consumers is fast and the other is slow, we need to wait for 
the slower one before starting processing the rest in the original 
Stream. We can choose to allow multiple consumers to address this by 
introducing a new concept Cursor that represents reading context. 
Cursor can be implemented as a new interface or Stream that refers to 
(and adds reference count to elements of) the original Stream's 
internal buffer.


Needs some more study to figure out if context approach is really 
better than pipe()-ing to new Stream instance.


* Splitting InputStream (ReadableStream) and OutputStream (WritableStream)
Writing part and reading part of the API can be split into two 

Re: Thoughts behind the Streams API ED

2013-11-06 Thread Takeshi Yoshino
On Wed, Nov 6, 2013 at 7:33 PM, Aymeric Vitte vitteayme...@gmail.comwrote:

  I have seen the different bugs too, some comments:

 - maybe I have missed some explaination or some obvious thing but I don't
 understand very well right now the difference/use between
 readable/writablebytestream and bytestream


ReadableByteStream and WritableByteStream are defining interfaces not only
for ByteStream but more generally for other APIs. For example, we discussed
how WebCrypto's encryption method should work with Stream concept recently,
and one idea you showed was making WebCrypto.subtle return an object (which
I called filter) to which we can pipe data. By defining a protocol how to
pass data to consumer as the WritableByteStream interface, we can reuse it
later for defining IDL for those filters. Similarly, ReadableByteStream can
provide uniform protocol how data producing APIs should communicate with
consumers.

ByteStream is now a class inheriting both ReadableByteStream and
WritableByteStream (sorry, I forgot to include inheritance info in the IDL).


 - pause/unpause: as far as I understand the whatwg spec does not recommend
 it but I don't understand the reasons. As I previously mentionned the idea
 is to INSERT a pause signal in the stream, you can not control the stream
 and therefore know when you are pausing it.


Maybe after decoupling the interface, pause/unpause are things to be added
to ByteStream? IIUC, pause prevents data from being read from a ByteStream,
and unpause removes the dam?


 - stop/resume: same, see my previous post, the difference is that the
 consuming API should clone the state of the operation and close the current
 operation as if eof was received, then restart from the clone on resume


Sorry that I haven't replied to your one.

Your post about those methods:
http://lists.w3.org/Archives/Public/public-webapps/2013OctDec/0343.html
WebCrypto ISSUE-22: http://www.w3.org/2012/webcrypto/track/issues/22

Maybe I still don't quite understand your ideas. Let me confirm.

stop() tells the consumer API implementing WritableByteStream that it
should behave as if it received EOF, but when resume() is called, restart
processing the data written between stop() call and resume() call as if the
API received data for the first time?

How should stop() work for ByteStream? ByteStream's read() method will
receive EOF at least once when all data written before stop() call has been
read, and it keeps returning EOF until resume() tells the ByteStream to
restart outputting?

I've been feeling that your use case is very specific to WebCrypto. Saving
state and restoring it sounds more like feature request for WebCrypto, not
a Stream.

But I'm a bit interested in what your stop()/resume() enables. With this
feature, ByteStream becomes message stream which is convenient for handling
WebSocket.


  - pipe []/fork: I don't see why the fast stream should wait for the slow
 one, so maybe the stream is forked and pause can be used for the slow one


There could be apps that want to limit memory usage strictly. We think
there're two strategies fork() can take.
a) wait until the slowest substream consumes
b) grow not to block the fastest substream while keeping data for the
slowest

a) is useful to limit memory usage. b) is more performance oriented.



 - flow control: could it be possible to advertise a maximum bandwidth rate
 for a stream?


It's currently communicated as window similar to TCP. Consumer can adjust
size argument of read() and frequency of read() call to match the
consumer's processing speed.


Re: Thoughts behind the Streams API ED

2013-11-05 Thread Takeshi Yoshino
FYI, I added a branch named Preview version into which suggestions are
incorporated aggressively to see how the API surface would be change.
https://dvcs.w3.org/hg/streams-api/raw-file/tip/preview.html
Please take a look if you're interested in.

For stabler version edited after having discussion, check ED as usual.


Re: Thoughts behind the Streams API ED

2013-11-04 Thread Takeshi Yoshino
On Tue, Nov 5, 2013 at 2:11 AM, Takeshi Yoshino tyosh...@google.com wrote:

 Feedback on Overlap thread, especially Issac's exhaustive list of
 considerations


Deleted citation by mistake. [1] is the Issac's post.


 [1]
 http://lists.w3.org/Archives/Public/public-webapps/2013JulSep/0355.html