Closed michz closed 2 years ago
The problem lies within stream_select() itself, that it a) does not abort when an exception is thrown, but continues with an empty syscall (you'd see the exception if stream_select() were to return later on), and b) counts the omitted file descriptors (and if that counter is greater than zero, it goes ahead with the select(2) syscall, even if nothing is in it).
Given that this is not an AMP bug, I have to close this issue.
To reproduce the hang:
<?php
$fds = [];
for ($i = 0; $i < 1023; $i++) {
$fds[] = fopen("/tmp/test/__0_a_evil_tmpfile.$i", 'w');
}
list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
$r = [$a];
$w = $e = [];
var_dump(stream_select($r, $w, $e, PHP_INT_MAX));
And then you can use set_error_handler(function() { throw new \Exception; });
to "hide" the exception.
I've re-reported it as https://github.com/php/php-src/issues/9590.
Agree, thanks :+1:
@bwoebi @michz Thanks for digging into this and opening the upstream issue!
amphp version: 2.6.2 parallel-functions version: 1.1.0 PHP version: tested with 7.4 and 8.1
Hi at all,
First of all: I know that
stream_select
does not work with file descriptors > 1024.Nevertheless, I expected amphp to fail cleanly when problems with file descriptors > 1024 are encountered (see #338 ).
Lately I encountered a case in production that caused some confusion on my end. I managed to break it down to the following minimal scenario:
The result is reproducible:
And then it hangs forever.
Doing an
strace
on the process shows, that it is waiting for aselect
without timeout and without any file descriptors it should check:The problem occurs regardless of the number of runners in the pool.
Using xdebug, I can trace it down until:
\stream_select
(containing a file descriptor in the first array, which is obviously too high – just as it is to be expected)throw
inside the event handler\stream_select
had been re-executed :thinking:I'm am kind of cueluess, to be honest. Especially, because I also saw processes correctly dying with this error instead of hanging. I could not, however, sort out under which exact circumstances it hangs and under which it fails correctly.
Does anybody have an idea what happens here? Might this be a bug in amphp or even php?
I could not trace it down further until now, sorry…
I have created a gist that contains the setup I used for reproduction: https://gist.github.com/michz/6cc16886693fa81518a4fd6e0e638177