/** * Adds the next request to pool and tracks what requests need to be * dereferenced when completing the pool. */ private function addNextRequest() { if ($this->isRealized || !$this->iter || !$this->iter->valid()) { return false; } $request = $this->iter->current(); $this->iter->next(); if (!$request instanceof RequestInterface) { throw new \InvalidArgumentException(sprintf('All requests in the provided iterator must implement ' . 'RequestInterface. Found %s', Core::describeType($request))); } // Be sure to use "lazy" futures, meaning they do not send right away. $request->getConfig()->set('future', 'lazy'); $this->attachListeners($request, $this->eventListeners); $response = $this->client->send($request); $hash = spl_object_hash($request); $this->waitQueue[$hash] = $response; // Use this function for both resolution and rejection. $fn = function ($value) use($request, $hash) { unset($this->waitQueue[$hash]); $result = $value instanceof ResponseInterface ? ['request' => $request, 'response' => $value, 'error' => null] : ['request' => $request, 'response' => null, 'error' => $value]; $this->deferred->progress($result); $this->addNextRequest(); }; $response->then($fn, $fn); return true; }
public function search($searchTarget = 'ssdp:all', $mx = 2) { $data = "M-SEARCH * HTTP/1.1\r\n"; $data .= "HOST: " . self::ADDRESS . "\r\n"; $data .= "MAN: \"ssdp:discover\"\r\n"; $data .= "MX: {$mx}\r\n"; $data .= "ST: {$searchTarget}\r\n"; $data .= "\r\n"; $socket = $this->multicast->createSender(); // TODO: The TTL for the IP packet SHOULD default to 2 and SHOULD be configurable. $timer = $this->loop->addTimer($mx, function () use($socket, &$deferred) { $deferred->resolve(); $socket->close(); }); $deferred = new Deferred(function () use($socket, &$timer) { // canceling resulting promise cancels timer and closes socket $timer->cancel(); $socket->close(); throw new RuntimeException('Cancelled'); }); $that = $this; $socket->on('message', function ($data, $remote) use($deferred, $that) { $message = $that->parseMessage($data, $remote); $deferred->progress($message); }); $socket->send($data, self::ADDRESS); return $deferred->promise(); }
/** @test */ public function progressIsAnAliasForNotify() { $deferred = new Deferred(); $sentinel = new \stdClass(); $mock = $this->createCallableMock(); $mock->expects($this->once())->method('__invoke')->with($sentinel); $deferred->promise()->then($this->expectCallableNever(), $this->expectCallableNever(), $mock); $deferred->progress($sentinel); }
public function readLength($bytes) { $deferred = new Deferred(); $oldsize = $this->stream->bufferSize; $this->stream->bufferSize = $bytes; $buffer = ''; $fn = function ($data, Stream $stream) use(&$buffer, &$bytes, $deferred, $oldsize, &$fn) { $bytes -= strlen($data); $buffer .= $data; $deferred->progress($data); if ($bytes === 0) { $stream->bufferSize = $oldsize; $stream->removeListener('data', $fn); $deferred->resolve($buffer); } else { $stream->bufferSize = $bytes; } }; $this->stream->on('data', $fn); return $deferred->promise(); }
private function finishResponse($request, $value, $hash) { unset($this->waitQueue[$hash]); $result = $value instanceof ResponseInterface ? ['request' => $request, 'response' => $value, 'error' => null] : ['request' => $request, 'response' => null, 'error' => $value]; $this->deferred->progress($result); }
/** * @param mixed $value */ public function progress($value) { $cleanup = $this->cleanup; $cleanup($this); return $this->deferred->progress($value); }