-
Notifications
You must be signed in to change notification settings - Fork 161
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
Prototyping several changes for better support for reading bytes #287
Conversation
This is an extended version of WritableStream with the following functionality:
See the example in the test file to see how this works for ReadFile/fread style source with buffer allocator residing in the source side. write() returns a structure representing the status of the operation and read() returns an object to acknowledge the operation. These are for synchronous pumping, but can be removed if it's considered to be too complex. async readInto() can be realized by using the writable side of the operation stream. You'll receive eof via write()'s return value. This serves for needs to allow users to bring their own buffer than allocating buffers inside a source. If write() being used for reading is confusing, we could rename write() of the operation stream to e.g. issue() and read() to accept(), take(), etc. |
I meant that I guess this single API can serve for various use cases. |
The following stuffs proposed in recent discussion are also incorporated
|
b4d5431
to
ff8e97c
Compare
Now, queue and promises are separated. See this file for ReadbleStream and WritableStream interface definition.
I haven't demonstrated, but:
|
I have also been trying to keep queue handling class useful for source/sink implementor. But not yet given good shape. |
Sorry for not yet having responded to your questions, Domenic. I'll respond to them from the office tomorrow... |
Domenic: Response to #287 (comment) cont'd
When we were discussing the idea of having a buffer pool inside a readable stream and giving them to the user on reading, we found that we need to explicitly tell the source when the buffer becomes ok to reuse. As you said,
In addition to that, I thought that similarly to bring-your-own-buffer model readable stream, we may want to use please-write-to-this-buffer model writable stream. I.e. suppose that we have a sink that prepares and exposes some memory region as an ArrayBuffer and ask the producer code to write bytes into it. To wrap this sink with some streams variant API, we need a method which returns a region for writing data and also returns some methods to tell the sink completion of the writing.
This reduces the number of ArrayBuffer allocation compared to please-give-me-a-filled-array-buffer model writable stream. This Anyway they're just attempts to address each of the semantics separately. Now, I'd like to go back to investigate which (set of) semantics we should support Source of bytes
Sink of bytes
|
Again, reply to Domenic's comment #287 (comment)
Right.
Yes. There could be some translation between each pair of source type and target type, but not always so simple and worth to be abstracted in the streams library, I guess. For byte streams, yes, I think it would be useful.
Right. It's inspired by TCP. For byte streams, we can specify how much data we want to receive from the remote host, read from kernel, read from other process, etc. using window. In some old thread, I said that I guessed it's not rare that we want to control the high water mark of the strategy from user code based on current situation e.g. back pressure from the sink the data read from the readable stream finally reaches. Basically, it's fine to understand this as a knob for adjusting hwm. |
Addition of window and space are just a bonus. I felt that they might be connected with the issue we're trying to solve, but it's almost turned out to be unrelated. So, I think we can post pone it. |
Continued from #253 (comment)
Does this affect public API (either for stream creators or users)? I notice the new comments at the top of the file (which are extremely helpful) have slightly different underlying sink/source designs. Instead of being based on strategy they give more direct control---which is probably a good change. Is that part of queue / stream separation?
These are interesting. To summarize:
I am not sure these are an improvement, personally. What was the motivation?
The addition of the "locked" state is hopefully not too annoying. Prototyping will help confirm. But in general (I know I'm repeating myself, sorry) I am in favor of changing the preconditions in ways that make things more straightforward. |
Creators are affected. Users are not affected.
Yes, that's exactly what I meant by queue / stream separation. Maybe there're still sources / sinks that really want to use a queue. We can provide some additional helper classes for them. I.e.
Thin.* are used by sources / sink which needs freedom.
After bunch of changes, I'm not so inclined to push this. They were for some simplification. I don't remember so much... I've almost reverted them for now.
We've almost reached agreement that it's fine as far as we can hide internal state and forbid operations on the stream while it's locked. Then, prohibiting everything should be fine. Yes, we need to be careful not to decrease usability. But maybe ok... On the latest commit, I've prototyped byte source / stream (reader) separation as discussed around #253 (comment). |
Please ignore files with top comment "WIP WIP WIP". They're incomplete snippets. |
Interfaces
Utility
Examples
Test
|
Almost all of the ideas prototyped in this branch has been implemented / abandoned / sublimed into somethings else and landed till e601d69. The idea of ReadableStream with acknowledgement is well described in some issues e.g. #324. The reference implementation has been drastically modified. Because of these reasons, we don't need to keep this PR any more. Closing. |
No description provided.