Hi Domenic,
Thanks for your response. Please see my embedded remarks below
(labeled with [GT]).
Regards, Gomer
--
Gomer Thomas Consulting, LLC
9810 132nd St NE
Arlington, WA 98223
Cell: 425-309-9933
-----Original Message-----
From: Domenic Denicola [mailto:[email protected]]
Sent: Thursday, March 17, 2016 11:56 AM
To: Gomer Thomas <[email protected]>; 'Jonathan Garbee'
<[email protected]>; 'Hallvord Reiar Michaelsen Steen'
<[email protected]>
Cc: 'WebApps WG' <[email protected]>
Subject: RE: [XHR]
From: Gomer Thomas [mailto:[email protected]]
> I looked at the Streams specification, and it seems pretty
immature and underspecified. I’m not sure it is usable by someone who doesn’t
already know how it is supposed to work before reading the specification. How
many of the major web browsers are supporting it?
Thanks for the feedback. Streams is intended to be a lower-level
primitive used by other specifications, primarily. By reading it you're
supposed to learn how to implement your own streams from basic underlying
source APIs.
[GT] It would be good to say this in the specification, and
reference some sample source APIs. (This is an example of what I meant when I
said it is very difficult to read the specification unless one already knows
how it is supposed to work.)
> (1) The constructor of the ReadableStream object is “defined”
by
> Constructor (underlyingSource = { }, {size, highWaterMark = 1 }
= { }
> ) The “specification” states that the underlyingSource object
“can”
> implement various methods, but it does not say anything about
how to
> create or identify a particular underlyingSource
As you noticed, specific underlying sources are left to other
places. Those could be other specs, like Fetch:
https://fetch.spec.whatwg.org/#concept-construct-readablestream
or it could be used by authors directly:
https://streams.spec.whatwg.org/#example-rs-push-no-backpressure
> In my case I want to receive a stream from a remote HTTP
server. What do I put in for the underlyingSource?
This is similar to asking the question "I want to create a
promise for an animation. What do I put in the `new Promise(...)` constructor?"
In other words, a ReadableStream is a data type that can stream anything, and
the actual capability needs to be supplied by your code. Fetch supplies one
underlying source, for HTTP responses.
> Also, what does the “highWaterMark” parameter mean? The
“specification” says it is part of the queuing strategy object, but it does not
say what it does.
Hmm, I think the links (if you follow them) are fairly clear.
https://streams.spec.whatwg.org/#queuing-strategy. Do you have any suggestions
on how to make it clearer?
[GT] I did follow the link before I sent in my questions. In
section 2.5 it says "The queuing strategy assigns a size to each chunk, and
compares the total size of all chunks in the queue to a specified number, known
as the high water mark. The resulting difference, high water mark minus total
size, is used to determine the desired size to fill the stream’s queue." It
appears that this is incorrect. It does not seem to jibe with the default value
and the examples. As far as I can tell from the default value and the examples,
the high water mark is not the total size of all chunks in the queue. It is the
number of chunks in the queue. Also, this is somewhat problematic as a measure
unless the chunks are uniform in size. If the chunks are required to all be the
same size, this greatly reduces the usefulness of the Streams concept.
> Is it the maximum number of bytes of unread data in the Stream?
If so, it should say so.
Close; it is the maximum number of bytes before a backpressure
signal is sent. But, that is already exactly what the above link (which was
found by clicking the links "queuing strategy" in the constructor definition)
says, so I am not sure what you are asking for.
> If the “size” parameter is omitted, is the underlyingSource
free to send chunks of any size, including variable sizes?
Upon re-reading, I agree it's not 100% clear that the size()
function maps to "The queuing strategy assigns a size to each chunk". However,
the behavior of how the stream uses the size() function is defined in a lot of
detail if you follow the spec. I agree maybe it could use some more
non-normative notes explaining, and will work to add some, but in the end if
you really want to understand what happens you need to either read the spec's
algorithms or wait for someone to write an in-depth tutorial somewhere like MDN.
> (2) The ReadableStream class has a “getReader()” method, but
the specification gives no hint as to the data type that this method returns. I
suspect that it is an object of the ReadableStreamReader class, but if so it
would be nice if the “specification” said so.
This is actually normatively defined if you click the link in the
step "Return AcquireReadableStreamReader(this)," whose first line tells you
what it constructs (indeed, a ReadableStreamReader).
[GT] My original question was directed at how an application can issue
an XMLHttpRequest() call and retrieve the results piecewise as they arrive,
rather than waiting for the entire response to arrive. It looks like Streams
might meet this need, but It would take quite a lot of study to figure out how
to make this solution work, and the actual code would be pretty complex. I
would also not be able to use this approach as a mature technology in a
cross-browser environment for quite a while -- years? I think we will need to
implement a non-standard solution based on WebSocket messages for now. We can
then revisit the issue later. Thanks again for your help.