Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[HttpClient] Fix Failed to open stream: Too many open files#45073
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Uh oh!
There was an error while loading.Please reload this page.
adrienfr commentedJan 19, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@nicolas-grekas I think the issue is related to $multi = (object) [//'handle' => $this->handle,//'handle' => &$this->handle,'logger' => &$this->logger,'pushedResponses' => &$this->pushedResponses,'dnsCache' => &$this->dnsCache,'handlesActivity' => &$this->handlesActivity,'openHandles' => &$this->openHandles,'execCounter' => &$this->execCounter,'pauseExpiries' => &$this->pauseExpiries,'lastTimeout' => &$this->lastTimeout, ];// Keep a dummy "onPush" reference to work around a refcount bug in PHPcurl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION,$this->onPush =staticfunction ($parent,$pushed,array$requestHeaders)use ($multi,$maxPendingPushes) {returnself::handlePush($parent,$pushed,$requestHeaders,$multi,$maxPendingPushes); }); It works. But I soon as I uncomment one of the One other thing I noticed, a lot more
var_dump($this->multi->handle); => . 854 / 4775 ( 17%)resource(15232) oftype (curl_multi).resource(15342) oftype (curl_multi).resource(15383) oftype (curl_multi)
var_dump($this->handle); => . 854 / 4775 ( 17%)resource(26271) oftype (curl_multi).resource(26500) oftype (curl_multi).resource(26569) oftype (curl_multi) |
adrienfr commentedJan 19, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@nicolas-grekas might have found a "leak" in if (\is_resource($this->handle) ||$this->handleinstanceof \CurlMultiHandle) {if (\defined('CURLMOPT_PUSHFUNCTION')) {curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION,null); }$active =0;while (\CURLM_CALL_MULTI_PERFORM ===curl_multi_exec($this->handle,$active));}foreach ($this->openHandlesas [$ch]) {if (\is_resource($ch) ||$chinstanceof \CurlHandle) {curl_setopt($ch, \CURLOPT_VERBOSE,false); }} If I add these 2 blocks (especially the one with the |
adrienfr commentedJan 19, 2022
Regarding this part added in your last PR, I don't really understand the goal but shouldn't we have a call to $this->share =curl_share_init();curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_DNS);curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_SSL_SESSION);if (\defined('CURL_LOCK_DATA_CONNECT')) {curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_CONNECT);} |
nicolas-grekas commentedJan 19, 2022
I wish I could reproduce locally. If you can share the code privately with me, you can reach me on Symfony's Slack. |
nicolas-grekas commentedJan 19, 2022
Can you please try this patch instead? --- a/src/Symfony/Component/HttpClient/Internal/CurlClientState.php+++ b/src/Symfony/Component/HttpClient/Internal/CurlClientState.php@@ -23,9 +23,9 @@ use Symfony\Component\HttpClient\Response\CurlResponse; */ final class CurlClientState extends ClientState {- /** @var \CurlMultiHandle|resource */+ /** @var \CurlMultiHandle|resource|null */ public $handle;- /** @var \CurlShareHandle|resource */+ /** @var \CurlShareHandle|resource|null */ public $share; /** @var PushedResponse[] */ public $pushedResponses = [];@@ -65,8 +65,17 @@ final class CurlClientState extends ClientState return; }- curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION, function ($parent, $pushed, array $requestHeaders) use ($maxPendingPushes) {- return $this->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes);+ // Clone to prevent a circular reference+ $multi = clone $this;+ $multi->handle = null;+ $multi->share = null;+ $multi->pushedResponses = &$this->pushedResponses;+ $multi->logger = &$this->logger;+ $multi->handlesActivity = &$this->handlesActivity;+ $multi->openHandles = &$this->openHandles;++ curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION, static function ($parent, $pushed, array $requestHeaders) use ($multi, $maxPendingPushes) {+ return $multi->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes); }); } |
adrienfr commentedJan 19, 2022
Thanks@nicolas-grekas for the patch, it works perfectly, no more issues! 🚀 |
nicolas-grekas commentedJan 19, 2022
Thank you@adrienfr. |
Uh oh!
There was an error while loading.Please reload this page.
With a large PHPUnit tests suite, I receive this error "Failed to open stream: Too many open files".
I found the original code from@nicolas-grekashere and with small adjustments, it resolves my issue.
Warning: tests for HttpClient are OK but would someone try with a real HTTP/2 client push? I was not able to test it.