PATH:
home
/
sparklp6
/
public_html
/
website_356c8563
/
nitropack
/
nitropack-sdk
/
vendor
/
nitropack
/
httpclient
/
src
<?php namespace NitroPack\HttpClient; class HttpClientMulti { /** @var HttpClient[] */ private $clients; /** @var null|callable */ private $successCallback; /** @var null|callable */ private $errorCallback; private $returnClients; private $intervals; private $clientRegistrationTimes; public function __construct() { $this->clients = array(); $this->intervals = array(); $this->successCallback = NULL; $this->errorCallback = NULL; $this->returnClients = true; $this->clientRegistrationTimes = new \SplObjectStorage(); } public function returnClients($status) { $this->returnClients = $status; } /** * @param HttpClient $client * @return void */ public function push($client) { $this->clients[] = $client; $this->clientRegistrationTimes->attach($client, time()); } /** * @return array|HttpClient[] */ public function getClients() { return $this->clients; } /** * @param callable $callback * @return void */ public function onSuccess($callback) { $this->successCallback = $callback; } /** * @param callable $callback * @return void */ public function onError($callback) { $this->errorCallback = $callback; } public function setInterval($callback, $interval) { // Interval is expected in ms $this->intervals[] = new HttpClientTimer($callback, $interval, HttpClientTimerType::INTERVAL); } public function executeIntervals() { if (!$this->intervals) return; foreach ($this->intervals as $task) { if ($task->hasToExecute()) { $task->execute(); } } } public function getNextInterval() { $delays = array(); foreach ($this->intervals as $task) { $delays[] = $task->getRemainingDelay(); } return min($delays); } public function fetchAll($follow_redirects = true, $method = "GET") { foreach ($this->clients as $client) { $client->fetch($follow_redirects, $method, true); } return $this->readAll(); } /* Returns an array with succeeded and failed clients * [ * [succeeded clients...], * [[failed client, exception]...] * ] */ public function readAll() { $succeededClients = []; $failedClients = []; while ($this->clients) { // Check whether to sleep using a syscall in order to conserve CPU usage $except = NULL; $read = []; $write = []; $remainingTimeouts = []; $canSleep = true; if ($this->intervals) { $nextInterval = $this->getNextInterval(); if ($nextInterval < 5) { $this->executeIntervals(); $nextInterval = $this->getNextInterval(); } $remainingTimeouts[] = $nextInterval / 1000; // We need to save the remaining delay in seconds } foreach ($this->clients as $client) { if ($client->getState() == HttpClientState::READY || $client->getState() == HttpClientState::INIT || $client->getState() == HttpClientState::CONNECT) { $canSleep = false; break; } switch ($client->getState()) { case HttpClientState::SSL_HANDSHAKE: $read[] = $client->sock; $write[] = $client->sock; $operationTimeout = $client->ssl_timeout ? $client->ssl_timeout : $client->timeout; $remainingTimeout = $operationTimeout - (microtime(true) - $client->ssl_negotiation_start); break; case HttpClientState::SEND_REQUEST: $write[] = $client->sock; $operationTimeout = $client->timeout; $remainingTimeout = $operationTimeout - (microtime(true) - $client->last_write); break; case HttpClientState::DOWNLOAD: if ($client->wasEmptyRead()) { $read[] = $client->sock; $operationTimeout = $client->timeout; $remainingTimeout = $operationTimeout - (microtime(true) - $client->last_read); } else { $canSleep = false; break 2; } break; default: $canSleep = false; break 2; } $remainingTimeouts[] = $remainingTimeout; } if ($canSleep) { $read = $read ? $read : NULL; $write = $write ? $write : NULL; if (!empty($read) || !empty($write)) { if (defined("NITROPACK_USE_MICROTIMEOUT") && NITROPACK_USE_MICROTIMEOUT) { stream_select($read, $write, $except, 0, NITROPACK_USE_MICROTIMEOUT); } else { $microtimeout = (int)(min($remainingTimeouts) * 1000000); if ($microtimeout > 0) { $streamsWithChange = stream_select($read, $write, $except, 0, 0); if ($streamsWithChange === 0) { usleep(20000);// 20ms } } } } else { usleep(20000);// 20ms } } // End check foreach ($this->clients as $client) { try { if ($client->asyncLoop()) { $this->removeClient($client); if ($this->returnClients) { $succeededClients[] = $client; } if ($this->successCallback) { call_user_func($this->successCallback, $client); } } } catch (\Exception $e) { $this->removeClient($client); if ($this->returnClients) { $failedClients[] = [$client, $e]; } if ($this->errorCallback) { call_user_func($this->errorCallback, $client, $e); } } } } return [$succeededClients, $failedClients]; } public function evictStuckClients($timeout = 300) { $evictedClients = []; $now = time(); foreach ($this->clients as $client) { try { $clientRegistrationTime = $this->clientRegistrationTimes->offsetGet($client); } catch (\UnexpectedValueException $e) { $clientRegistrationTime = 0; // Weird client - remove it } if ($now - $clientRegistrationTime >= $timeout) { $evictedClients[] = $client; //echo sprintf("Evicting stuck client for %s in state %s \n", $client->URL, $client->getState()); $client->abort(); $this->removeClient($client); } } return $evictedClients; } public function removeClient($client) { $index = array_search($client, $this->clients, true); if ($index !== false) { // Index can be false if the client has been evicted earlier array_splice($this->clients, $index, 1); } if ($this->clientRegistrationTimes->offsetExists($client)) { // Offset may not exist if the client has been evicted earlier $this->clientRegistrationTimes->detach($client); } } }
[-] HttpClientProxy.php
[edit]
[-] .htaccess
[edit]
[-] HttpConfig.php
[edit]
[-] Logger.php
[edit]
[-] HttpClientTimerType.php
[edit]
[+]
StreamFilter
[-] HttpClientMulti.php
[edit]
[-] 57999
[edit]
[-] HttpClientSocksProxy.php
[edit]
[+]
Commands
[-] HttpClientSocks4Proxy.php
[edit]
[-] HttpClientTimer.php
[edit]
[-] HttpClientState.php
[edit]
[-] 7765
[edit]
[+]
..
[+]
Exceptions