Unable to set stream resource to non-blocking mode [not STDIN or STDOUT]
CViniciusSDias opened this issue ยท 5 comments
I was able to reproduce the following error in several Windows machines: when trying to read a text file using ReadableResourceStream
I receive RuntimeException: Unable to set stream resource to non-blocking mode.
Here is an example code:
<?php
use React\EventLoop\Factory;
use React\Stream\ReadableResourceStream;
require_once 'vendor/autoload.php';
$loop = Factory::create();
$arquivo = fopen('existing_file.txt', 'r+');
$stream = new ReadableResourceStream($arquivo, $loop);
$stream->on('data', function (string $data) {
echo $data;
});
$loop->run();
And here is the full output:
PHP Fatal error: Uncaught RuntimeException: Unable to set stream resource to non-blocking mode in C:\Users\carlo\OneDrive\Documentos\reactphp-windows\vendor\react\stream\src\ReadableResourceStream.php:58
Stack trace:
#0 C:\Users\carlo\OneDrive\Documentos\reactphp-windows\index.php(11): React\Stream\ReadableResourceStream->__construct(Resource id #17, Object(React\EventLoop\StreamSelectLoop))
#1 {main}
thrown in C:\Users\carlo\OneDrive\Documentos\reactphp-windows\vendor\react\stream\src\ReadableResourceStream.php on line 58
Fatal error: Uncaught RuntimeException: Unable to set stream resource to non-blocking mode in C:\Users\carlo\OneDrive\Documentos\reactphp-windows\vendor\react\stream\src\ReadableResourceStream.php on line 58
RuntimeException: Unable to set stream resource to non-blocking mode in C:\Users\carlo\OneDrive\Documentos\reactphp-windows\vendor\react\stream\src\ReadableResourceStream.php on line 58
Call Stack:
0.0002 393608 1. {main}() C:\Users\carlo\OneDrive\Documentos\reactphp-windows\index.php:0
0.0046 612240 2. React\Stream\ReadableResourceStream->__construct($stream = resource(17) of type (stream), $loop = class React\EventLoop\StreamSelectLoop { private $futureTickQueue = class React\EventLoop\Tick\FutureTickQueue { private $queue = class SplQueue { ... } }; private $timers = class React\EventLoop\Timer\Timers { private $time = NULL; private $timers = [...]; private $schedule = [...]; private $sorted = TRUE; private $useHighResolution = TRUE }; private $readStreams = []; private $readListeners = []; private $writeStreams = []; private $writeListeners = []; private $running = NULL; private $pcntl = FALSE; private $pcntlPoll = FALSE; private $signals = class React\EventLoop\SignalsHandler { private $signals = [...] } }, $readChunkSize = ???) C:\Users\carlo\OneDrive\Documentos\reactphp-windows\index.php:11
System info:
- Windows 11
- PHP 8.1.5
- react/event-loop version: v1.3.0
- react/stream version: v1.2.0
Hey @CViniciusSDias, thanks for all the input ๐
When it comes to working with the filesystem it gets a bit tricky. The problem is that the filesystem is inherently blocking, so we have no choice to be blocking as well (fopen()
is also blocking).
It is described inside the documentation that when you try to give something blocking into the ReadableResourceStream
class, it tries to enable non-blocking mode on the stream resource which is not supported under Windows and will throw a RuntimeException
.
As you can see we're aware of this behavior. If you want, you can get rid of the RuntimeException
inside your project, but we can't do that inside our reactphp/stream component. You can also try the same under another operating system or take a look a the reactphp/filesystem (still experimental).
Maybe a non async approach is the way to go here, even if it's blocking, in most cases it might be fast enough.
I hope this helps.
The documentation states that
this is not supported by pipes on Windows (STDIN etc.)
But what I am trying to open is not a pipe. It's a regular file. Is that also not supported?
Beware not to take this sentence out of context. The full section of the documentation states:
Internally, this class tries to enable non-blocking mode on the stream resource which may not be supported for all stream resources. Most notably, this is not supported by pipes on Windows (STDIN etc.). If this fails, it will throw a RuntimeException:
We know this is not supported by pipes on Windows and your use case doesn't appear to be supported either. When it comes to working with the filesystem in combination with streams, the documentation also says this inside the usage chapter:
Note that this example uses fopen() for illustration purposes only. This should not be used in a truly async program because the filesystem is inherently blocking and each call could potentially take several seconds. See also creating streams for more sophisticated examples.
I hope this clears things up ๐
@SimonFrings , actually that was not very clear but while I was writing an example of non-blocking code that runs on Windows I saw the note on PHP's documentation:
On Windows, this has no affect on local files. Non-blocking IO for local files is not supported on Windows.
So yes, now I understand the behavior. Thank you for replying. :-D
I believe this has been answered, so I'm closing this for now. Please come back with more details if this problem persists and we can always reopen this ๐