/** * Create a new file driven handler instance. * * @param \Illuminate\Filesystem\Filesystem $files * @param React\EventLoop\LoopInterface $loop * @param string $path * * @return void */ public function __construct(Factory $factory, LoopInterface $loop, Server $server, $lifetime) { $this->factory = $factory; $this->lifetime = $lifetime; $this->server = $server; $this->loop = $loop; // PING redis connection every 5 minutes // and try to reconnect on connection error $this->timer = $loop->addPeriodicTimer(60 * 1, function () use($server) { $this->promise->then(function ($client) use($server) { $client->PING()->then(function ($pong) use($server) { $server->log('Redis server responded ping with: %s', [$pong]); return $pong == 'PONG'; }, function ($e) { return $this->reconnectByError($e); }); }); }); // server statistics for redis connection $this->loop->addPeriodicTimer(60 * 30, function () { $this->server->log('Server statistics to the last 30 minutes.'); $this->server->log('Best time of %fs, poor time of %fs and a average of %f seconds for total %d requests.', array_values($this->statistics)); $this->statistics = array('best' => 0, 'poor' => 0, 'avg' => 0, 'total' => 0); }); }
/** * Returns a readable plain text stream for the given ResponseInterface * * @param PromiseInterface $promise Promise<ResponseInterface> * @return ReadableStreamInterface */ public function parsePlainStream(PromiseInterface $promise) { // text/plain return Stream\unwrapReadable($promise->then(function (ResponseInterface $response) { return $response->getBody(); })); }
public function parsePlainStream(PromiseInterface $promise) { // text/plain $out = new ReadableStream(); // try to cancel promise once the stream closes if ($promise instanceof CancellablePromiseInterface) { $out->on('close', function () use($promise) { $promise->cancel(); }); } $promise->then(function ($response) use($out) { $out->close(); }, function ($error) use($out) { $out->emit('error', array($error, $out)); $out->close(); }, function ($progress) use($out) { if (is_array($progress) && isset($progress['responseStream'])) { $stream = $progress['responseStream']; /* @var $stream React\Stream\Stream */ // hack to do not buffer stream contents in body $stream->removeAllListeners('data'); // got a streaming HTTP response => forward each data chunk to the resulting output stream $stream->on('data', function ($data) use($out) { $out->emit('data', array($data, $out)); }); } }); return $out; }
function assertOkay(PromiseInterface $promise, $name = 'end') { return $promise->then(function ($stream) use($name) { echo 'EXPECTED: connection to ' . $name . ' OK' . PHP_EOL; $stream->close(); }, function (Exception $error) use($name) { echo 'FAIL: connection to ' . $name . ' failed: '; ex($error); }); }
/** * Instantiate new unwrapped writable stream for given `Promise` which resolves with a `WritableStreamInterface`. * * @param PromiseInterface $promise Promise<WritableStreamInterface, Exception> */ public function __construct(PromiseInterface $promise) { $out = $this; $store =& $this->stream; $buffer =& $this->buffer; $ending =& $this->ending; $closed =& $this->closed; $this->promise = $promise->then(function ($stream) { if (!$stream instanceof WritableStreamInterface) { throw new InvalidArgumentException('Not a writable stream'); } return $stream; })->then(function (WritableStreamInterface $stream) use($out, &$store, &$buffer, &$ending, &$closed) { // stream is already closed, make sure to close output stream if (!$stream->isWritable()) { $out->close(); return $stream; } // resolves but output is already closed, make sure to close stream silently if ($closed) { $stream->close(); return $stream; } // forward drain events for back pressure $stream->on('drain', function () use($out) { $out->emit('drain', array($out)); }); // error events cancel output stream $stream->on('error', function ($error) use($out) { $out->emit('error', array($error, $out)); $out->close(); }); // close both streams once either side closes $stream->on('close', array($out, 'close')); $out->on('close', array($stream, 'close')); if ($buffer !== '') { // flush buffer to stream and check if its buffer is not exceeded $drained = $stream->write($buffer) !== false; $buffer = ''; if ($drained) { // signal drain event, because the output stream previous signalled a full buffer $out->emit('drain', array($out)); } } if ($ending) { $stream->end(); } else { $store = $stream; } return $stream; }, function ($e) use($out) { $out->emit('error', array($e, $out)); $out->close(); }); }
/** * Converts a Promise to an Observable sequence * * @param \React\Promise\PromiseInterface $promise * @return \Rx\Observable\AnonymousObservable */ public static function toObservable(PromiseInterface $promise) { return Observable::defer(function () use($promise) { $subject = new AsyncSubject(); $promise->then(function ($value) use($subject) { $subject->onNext($value); $subject->onCompleted(); }, [$subject, "onError"]); return $subject; }); }
public function __construct(ReactPromise $promise) { $promise->then(function (ResponseInterface $response) { $this->state = Promise::FULFILLED; $this->response = $response; }, function (\Exception $error) { $this->state = Promise::REJECTED; $this->exception = $error; }); $this->promise = $promise; }
public function __construct(React\Promise\PromiseInterface $promise) { $promise->then(function ($data) { $this->isResolved = TRUE; $this->data = $data; }, function ($err) { $this->isResolved = TRUE; $this->error = $err; }); $this->promise = $promise; }
/** * Allow to apply callable when the promise resolve. * * @param callable|null $onFulfilled * @param callable|null $onRejected * * @return Promise */ public function then(callable $onFulfilled = null, callable $onRejected = null) { $this->promise->then(function () use($onFulfilled) { if (null !== $onFulfilled) { call_user_func($onFulfilled, $this->response); } }, function () use($onRejected) { if (null !== $onRejected) { call_user_func($onRejected, $this->exception); } }); return $this; }
/** * Converts a Promise to an Observable sequence * * @param \React\Promise\PromiseInterface $promise * @return \Rx\Observable\AnonymousObservable */ public static function toObservable(PromiseInterface $promise) { return Observable::defer(function () use($promise) { $subject = new AsyncSubject(); $promise->then(function ($value) use($subject) { $subject->onNext($value); $subject->onCompleted(); }, function ($error) use($subject) { $error = $error instanceof \Exception ? $error : new RejectedPromiseException($error); $subject->onError($error); }); return $subject; }); }
private function waitFor(PromiseInterface $promise) { $resolved = null; $exception = null; $promise->then(function ($c) use(&$resolved) { $resolved = $c; }, function ($error) use(&$exception) { $exception = $error; }); while ($resolved === null && $exception === null) { self::$loop->tick(); } if ($exception !== null) { throw $exception; } return $resolved; }
/** * Instantiate new unwrapped readable stream for given `Promise` which resolves with a `ReadableStreamInterface`. * * @param PromiseInterface $promise Promise<ReadableStreamInterface, Exception> */ public function __construct(PromiseInterface $promise) { $out = $this; $closed =& $this->closed; $this->promise = $promise->then(function ($stream) { if (!$stream instanceof ReadableStreamInterface) { throw new InvalidArgumentException('Not a readable stream'); } return $stream; })->then(function (ReadableStreamInterface $stream) use($out, &$closed) { // stream is already closed, make sure to close output stream if (!$stream->isReadable()) { $out->close(); return $stream; } // resolves but output is already closed, make sure to close stream silently if ($closed) { $stream->close(); return $stream; } // stream any writes into output stream $stream->on('data', function ($data) use($out) { $out->emit('data', array($data, $out)); }); // forward end events and close $stream->on('end', function () use($out, &$closed) { if (!$closed) { $out->emit('end', array($out)); $out->close(); } }); // error events cancel output stream $stream->on('error', function ($error) use($out) { $out->emit('error', array($error, $out)); $out->close(); }); // close both streams once either side closes $stream->on('close', array($out, 'close')); $out->on('close', array($stream, 'close')); return $stream; }, function ($e) use($out) { $out->emit('error', array($e, $out)); $out->close(); }); }
/** * block waiting for the given $promise to resolve * * @param PromiseInterface $promise * @param LoopInterface $loop * @return mixed returns whatever the promise resolves to * @throws Exception when the promise is rejected */ function await(PromiseInterface $promise, LoopInterface $loop) { $wait = true; $resolved = null; $exception = null; $promise->then(function ($c) use(&$resolved, &$wait, $loop) { $resolved = $c; $wait = false; $loop->stop(); }, function ($error) use(&$exception, &$wait, $loop) { $exception = $error; $wait = false; $loop->stop(); }); while ($wait) { $loop->run(); } if ($exception !== null) { throw $exception; } return $resolved; }
private function addShadow() { // Get the result and error when the promise is resolved. Note that // calling this function might trigger the resolution immediately. $this->wrappedPromise->then(function ($value) { $this->isRealized = true; $this->result = $value; $this->waitfn = $this->cancelfn = null; }, function ($error) { $this->isRealized = true; $this->error = $error; $this->waitfn = $this->cancelfn = null; }); }
function timeout(PromiseInterface $promise, $time, LoopInterface $loop) { // cancelling this promise will only try to cancel the input promise, // thus leaving responsibility to the input promise. $canceller = null; if ($promise instanceof CancellablePromiseInterface) { $canceller = array($promise, 'cancel'); } return new Promise(function ($resolve, $reject) use($loop, $time, $promise) { $timer = $loop->addTimer($time, function () use($time, $promise, $reject) { $reject(new TimeoutException($time, 'Timed out after ' . $time . ' seconds')); if ($promise instanceof CancellablePromiseInterface) { $promise->cancel(); } }); $promise->then(function ($v) use($timer, $loop, $resolve) { $loop->cancelTimer($timer); $resolve($v); }, function ($v) use($timer, $loop, $reject) { $loop->cancelTimer($timer); $reject($v); }); }, $canceller); }
/** * Return Promise that absorbs rejects, excluding fatal Throwable. * @param PromiseInterface $promise * @return PromiseInterface */ public static function safePromise(PromiseInterface $promise) { return $promise->then(null, function ($value) { if (TypeUtils::isFatalThrowable($value)) { throw $value; } return $value; }); }
private function assertArraySubsetPromise($subset, PromiseInterface $promise) { $array = null; $promise->then(function ($value) use(&$array) { $array = $value->toArray(); }); $this->assertArraySubset($subset, $array); }
private function getPromiseValue(PromiseInterface $promise) { $capturedValue = null; $promise->then(function ($value) use(&$capturedValue) { $capturedValue = $value; }); return $capturedValue; }
/** * @param PromiseInterface $promise * @return Observable */ function fromPromise(PromiseInterface $promise) { return Observable::defer(function () use($promise) { $subject = new AsyncSubject(); $promise->then(function ($res) use($subject) { $subject->onNext($res); $subject->onCompleted(); }, [$subject, 'onError']); return $subject; }); }
/** * Process a result as a promise * * @param \React\Promise\PromiseInterface $promise * @param \Thruway\Message\InvocationMessage $msg * @param \Thruway\ClientSession $session * @param array $registration */ private function processResultAsPromise(PromiseInterface $promise, InvocationMessage $msg, ClientSession $session, $registration) { $promise->then(function ($promiseResults) use($msg, $session) { $options = new \stdClass(); if ($promiseResults instanceof Result) { $yieldMsg = new YieldMessage($msg->getRequestId(), $options, $promiseResults->getArguments(), $promiseResults->getArgumentsKw()); } else { $promiseResults = is_array($promiseResults) ? $promiseResults : [$promiseResults]; $promiseResults = !$this::is_list($promiseResults) ? [$promiseResults] : $promiseResults; $yieldMsg = new YieldMessage($msg->getRequestId(), $options, $promiseResults); } $session->sendMessage($yieldMsg); }, function ($e) use($msg, $session, $registration) { if ($e instanceof \Exception) { $this->processExceptionFromRPCCall($session, $msg, $registration, $e); return; } $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg); $errorMsg->setErrorURI($registration['procedure_name'] . '.error'); $session->sendMessage($errorMsg); }, function ($results) use($msg, $session, $registration) { $options = new \stdClass(); $options->progress = true; if ($results instanceof Result) { $yieldMsg = new YieldMessage($msg->getRequestId(), $options, $results->getArguments(), $results->getArgumentsKw()); } else { $results = is_array($results) ? $results : [$results]; $results = !$this::is_list($results) ? [$results] : $results; $yieldMsg = new YieldMessage($msg->getRequestId(), $options, $results); } $session->sendMessage($yieldMsg); }); }
/** * Returns a promise that is invoked when the pool completed. There will be * no passed value. * * {@inheritdoc} */ public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) { return $this->promise->then($onFulfilled, $onRejected, $onProgress); }
private function assertPromiseYields($expected, PromiseInterface $promise) { $id = sizeof($this->promiseExpectations); $this->promiseExpectations[$id] = ['expected' => $expected]; $promise->then(function ($value) use($id, $expected) { $this->promiseExpectations[$id]['actual'] = $value; }); }