Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
extend base React\Stream\Stream class by checking stream meta data for remaining stream buffer before reading from blocking streams
<?php
// extend base Stream class by checking stream meta data for remaining stream buffer before reading from blocking streams
// heavily inspired by: https://github.com/clue/Worker/commit/8c6d7a4e733f0ee5aa431ffda1d4929229ae2336
class StreamUnblock extends \React\Stream\Stream
{
public function handleData($stream)
{
// check stream meta data for remaining buffer
// yes, the manual explicitly says this value SHOULD NOT be used,
// but this has been confirmed to work around blocking on blocking streams
$meta = stream_get_meta_data($stream);
$len = $meta['unread_bytes'];
if ($len === 0) {
// length unknown (usual case), read up to one chunk from incoming streams
$len = $this->bufferSize;
} else if ($len > $this->bufferSize) {
// buffer length known and bigger than chunk, read exactly one chunk from buffer
$len = $this->bufferSize;
} else {
// small buffer remaining, read EXACTLY remaining buffer. execeeding buffer length WILL block fread() when no more data is incoming
}
// this above mess could probably be cleaned up, but I left it unchanged to make it more clear what's going on:
// $len = $this->bufferSize;
// if ($meta['unread_bytes'] !== 0 && $meta['unread_bytes'] < $len) { $len = $meta['unread_bytes']; }
$data = fread($stream, $len);
$this->emit('data', array($data, $this));
if (!is_resource($stream) || feof($stream)) {
$this->end();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.