-
-
Notifications
You must be signed in to change notification settings - Fork 62
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
Changes to Buffer::write() behaviour #16
Conversation
- Returns a Promise instead of a boolean indication that the buffer is full - "buffer full"-state is propagated via "full"-event - Updated BufferedSink, WritableStream and ThroughStream to return a FulfilledPromise on write() - Updated Util to properly handle "full"-event when piping - Updated CompositeStream to forward full-event for piping
I agree that this is odd and should be addressed. 👍
It's my understanding that most consumers of the stream API do not really care about when the buffer has been drained. In these cases, this change introduces quite a bit of overhead. Do you happen to have a particular use case for this change? |
Use-case: A CPU-intensive task is sending status updates via sockets to another system. In the first implementation I sent the status update, and scheduled task-continuation to the next (or future) tick. This resulted in the status updates never being sent. More correct would be to continue the task as soon as the status update is on the wire, hence I looked for a way to hook to this event. But you are correct; the current implementation is probably to heavy for all those use-cases where the promised would be ignored. Maybe we could change it that way:
Those two changes would allow for Stream to be decorated with an implementation which creates write-promises. (The implementation could be either part of react/stream or customized to the user's need in their (my 😉) package) Alternatively this could be solved by inheritance...but I usually prefer composition over inheritance. 😄 |
I'm not sure it's likely we'll see support for blocking functions any time soon, given that even the FAQs warn against this.
This should already be possible by hooking into the $stream = new Stream($resource, $loop);
$buffer = $stream->getBuffer();
$buffer->once('full-drain', function () {
// buffer has been flushed, now do the heavy lifting
secondStep();
});
$response = firstStep();
$stream->write($response); |
Well, the CPU intensive task can easily split up into many parts and scheduled async. It really doesn't matter into how many parts I split, the buffer just does not seem to get flushed, if I continue with
|
Closed via #43. |
The following is a proposal for a BC breaking change regarding the
WritableStreamInterface::write()
signature.Currently the
WritableStreamInterface
does not hint on any return type.WritableStream
is avoid
,Stream
returns aboolean
indicating whether the internal buffer is full (as described in the README).This PR changes
Stream
,WritableStream
,CompositeStream
andThroughStream
so that theirwrite
-methods all return aReact\Promise\PromiseInterface
.Stream
(or ratherBuffer
) resolves this promise whenfwrite
accepted all bytes. The other implementations all return aFulfilledPromise
(instead of being avoid
)Util::pipe()
embraces this change by triggeringpause()
on the readable stream, when it encounters thefull
-event instead ofwrite()
returning false.CompositeStream
therefore also needs to forward thefull
-event from the writable stream to itself.Tests have been amended/fixed to reflect the changed behavior.
TODO:
full
event? Maybebuffer-full
?