summaryrefslogtreecommitdiffstats
path: root/vendor/react/promise-timer/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/react/promise-timer/src')
-rw-r--r--vendor/react/promise-timer/src/TimeoutException.php35
-rw-r--r--vendor/react/promise-timer/src/functions.php330
-rw-r--r--vendor/react/promise-timer/src/functions_include.php7
3 files changed, 372 insertions, 0 deletions
diff --git a/vendor/react/promise-timer/src/TimeoutException.php b/vendor/react/promise-timer/src/TimeoutException.php
new file mode 100644
index 0000000..7f03ba0
--- /dev/null
+++ b/vendor/react/promise-timer/src/TimeoutException.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace React\Promise\Timer;
+
+use RuntimeException;
+
+class TimeoutException extends RuntimeException
+{
+ /** @var float */
+ private $timeout;
+
+ /**
+ * @param float $timeout
+ * @param string|null $message
+ * @param int|null $code
+ * @param null|\Exception|\Throwable $previous
+ */
+ public function __construct($timeout, $message = '', $code = 0, $previous = null)
+ {
+ // Preserve compatibility with our former nullable signature, but avoid invalid arguments for the parent constructor:
+ parent::__construct((string) $message, (int) $code, $previous);
+
+ $this->timeout = (float) $timeout;
+ }
+
+ /**
+ * Get the timeout value in seconds.
+ *
+ * @return float
+ */
+ public function getTimeout()
+ {
+ return $this->timeout;
+ }
+}
diff --git a/vendor/react/promise-timer/src/functions.php b/vendor/react/promise-timer/src/functions.php
new file mode 100644
index 0000000..b72bf36
--- /dev/null
+++ b/vendor/react/promise-timer/src/functions.php
@@ -0,0 +1,330 @@
+<?php
+
+namespace React\Promise\Timer;
+
+use React\EventLoop\Loop;
+use React\EventLoop\LoopInterface;
+use React\Promise\Promise;
+use React\Promise\PromiseInterface;
+
+/**
+ * Cancel operations that take *too long*.
+ *
+ * You need to pass in an input `$promise` that represents a pending operation
+ * and timeout parameters. It returns a new promise with the following
+ * resolution behavior:
+ *
+ * - If the input `$promise` resolves before `$time` seconds, resolve the
+ * resulting promise with its fulfillment value.
+ *
+ * - If the input `$promise` rejects before `$time` seconds, reject the
+ * resulting promise with its rejection value.
+ *
+ * - If the input `$promise` does not settle before `$time` seconds, *cancel*
+ * the operation and reject the resulting promise with a [`TimeoutException`](#timeoutexception).
+ *
+ * Internally, the given `$time` value will be used to start a timer that will
+ * *cancel* the pending operation once it triggers. This implies that if you
+ * pass a really small (or negative) value, it will still start a timer and will
+ * thus trigger at the earliest possible time in the future.
+ *
+ * If the input `$promise` is already settled, then the resulting promise will
+ * resolve or reject immediately without starting a timer at all.
+ *
+ * This function takes an optional `LoopInterface|null $loop` parameter that can be used to
+ * pass the event loop instance to use. You can use a `null` value here in order to
+ * use the [default loop](https://github.com/reactphp/event-loop#loop). This value
+ * SHOULD NOT be given unless you're sure you want to explicitly use a given event
+ * loop instance.
+ *
+ * A common use case for handling only resolved values looks like this:
+ *
+ * ```php
+ * $promise = accessSomeRemoteResource();
+ * React\Promise\Timer\timeout($promise, 10.0)->then(function ($value) {
+ * // the operation finished within 10.0 seconds
+ * });
+ * ```
+ *
+ * A more complete example could look like this:
+ *
+ * ```php
+ * $promise = accessSomeRemoteResource();
+ * React\Promise\Timer\timeout($promise, 10.0)->then(
+ * function ($value) {
+ * // the operation finished within 10.0 seconds
+ * },
+ * function ($error) {
+ * if ($error instanceof React\Promise\Timer\TimeoutException) {
+ * // the operation has failed due to a timeout
+ * } else {
+ * // the input operation has failed due to some other error
+ * }
+ * }
+ * );
+ * ```
+ *
+ * Or if you're using [react/promise v3](https://github.com/reactphp/promise):
+ *
+ * ```php
+ * React\Promise\Timer\timeout($promise, 10.0)->then(function ($value) {
+ * // the operation finished within 10.0 seconds
+ * })->catch(function (React\Promise\Timer\TimeoutException $error) {
+ * // the operation has failed due to a timeout
+ * })->catch(function (Throwable $error) {
+ * // the input operation has failed due to some other error
+ * });
+ * ```
+ *
+ * As discussed above, the [`timeout()`](#timeout) function will take care of
+ * the underlying operation if it takes *too long*. In this case, you can be
+ * sure the resulting promise will always be rejected with a
+ * [`TimeoutException`](#timeoutexception). On top of this, the function will
+ * try to *cancel* the underlying operation. Responsibility for this
+ * cancellation logic is left up to the underlying operation.
+ *
+ * - A common use case involves cleaning up any resources like open network
+ * sockets or file handles or terminating external processes or timers.
+ *
+ * - If the given input `$promise` does not support cancellation, then this is a
+ * NO-OP. This means that while the resulting promise will still be rejected,
+ * the underlying input `$promise` may still be pending and can hence continue
+ * consuming resources
+ *
+ * On top of this, the returned promise is implemented in such a way that it can
+ * be cancelled when it is still pending. Cancelling a pending promise will
+ * cancel the underlying operation. As discussed above, responsibility for this
+ * cancellation logic is left up to the underlying operation.
+ *
+ * ```php
+ * $promise = accessSomeRemoteResource();
+ * $timeout = React\Promise\Timer\timeout($promise, 10.0);
+ *
+ * $timeout->cancel();
+ * ```
+ *
+ * For more details on the promise cancellation, please refer to the
+ * [Promise documentation](https://github.com/reactphp/promise#cancellablepromiseinterface).
+ *
+ * If you want to wait for multiple promises to resolve, you can use the normal
+ * promise primitives like this:
+ *
+ * ```php
+ * $promises = array(
+ * accessSomeRemoteResource(),
+ * accessSomeRemoteResource(),
+ * accessSomeRemoteResource()
+ * );
+ *
+ * $promise = React\Promise\all($promises);
+ *
+ * React\Promise\Timer\timeout($promise, 10)->then(function ($values) {
+ * // *all* promises resolved
+ * });
+ * ```
+ *
+ * The applies to all promise collection primitives alike, i.e. `all()`,
+ * `race()`, `any()`, `some()` etc.
+ *
+ * For more details on the promise primitives, please refer to the
+ * [Promise documentation](https://github.com/reactphp/promise#functions).
+ *
+ * @param PromiseInterface<mixed, \Throwable|mixed> $promise
+ * @param float $time
+ * @param ?LoopInterface $loop
+ * @return PromiseInterface<mixed, TimeoutException|\Throwable|mixed>
+ */
+function timeout(PromiseInterface $promise, $time, LoopInterface $loop = null)
+{
+ // cancelling this promise will only try to cancel the input promise,
+ // thus leaving responsibility to the input promise.
+ $canceller = null;
+ if (\method_exists($promise, 'cancel')) {
+ // pass promise by reference to clean reference after cancellation handler
+ // has been invoked once in order to avoid garbage references in call stack.
+ $canceller = function () use (&$promise) {
+ $promise->cancel();
+ $promise = null;
+ };
+ }
+
+ if ($loop === null) {
+ $loop = Loop::get();
+ }
+
+ return new Promise(function ($resolve, $reject) use ($loop, $time, $promise) {
+ $timer = null;
+ $promise = $promise->then(function ($v) use (&$timer, $loop, $resolve) {
+ if ($timer) {
+ $loop->cancelTimer($timer);
+ }
+ $timer = false;
+ $resolve($v);
+ }, function ($v) use (&$timer, $loop, $reject) {
+ if ($timer) {
+ $loop->cancelTimer($timer);
+ }
+ $timer = false;
+ $reject($v);
+ });
+
+ // promise already resolved => no need to start timer
+ if ($timer === false) {
+ return;
+ }
+
+ // start timeout timer which will cancel the input promise
+ $timer = $loop->addTimer($time, function () use ($time, &$promise, $reject) {
+ $reject(new TimeoutException($time, 'Timed out after ' . $time . ' seconds'));
+
+ // try to invoke cancellation handler of input promise and then clean
+ // reference in order to avoid garbage references in call stack.
+ if (\method_exists($promise, 'cancel')) {
+ $promise->cancel();
+ }
+ $promise = null;
+ });
+ }, $canceller);
+}
+
+/**
+ * Create a new promise that resolves in `$time` seconds.
+ *
+ * ```php
+ * React\Promise\Timer\sleep(1.5)->then(function () {
+ * echo 'Thanks for waiting!' . PHP_EOL;
+ * });
+ * ```
+ *
+ * Internally, the given `$time` value will be used to start a timer that will
+ * resolve the promise once it triggers. This implies that if you pass a really
+ * small (or negative) value, it will still start a timer and will thus trigger
+ * at the earliest possible time in the future.
+ *
+ * This function takes an optional `LoopInterface|null $loop` parameter that can be used to
+ * pass the event loop instance to use. You can use a `null` value here in order to
+ * use the [default loop](https://github.com/reactphp/event-loop#loop). This value
+ * SHOULD NOT be given unless you're sure you want to explicitly use a given event
+ * loop instance.
+ *
+ * The returned promise is implemented in such a way that it can be cancelled
+ * when it is still pending. Cancelling a pending promise will reject its value
+ * with a `RuntimeException` and clean up any pending timers.
+ *
+ * ```php
+ * $timer = React\Promise\Timer\sleep(2.0);
+ *
+ * $timer->cancel();
+ * ```
+ *
+ * @param float $time
+ * @param ?LoopInterface $loop
+ * @return PromiseInterface<void, \RuntimeException>
+ */
+function sleep($time, LoopInterface $loop = null)
+{
+ if ($loop === null) {
+ $loop = Loop::get();
+ }
+
+ $timer = null;
+ return new Promise(function ($resolve) use ($loop, $time, &$timer) {
+ // resolve the promise when the timer fires in $time seconds
+ $timer = $loop->addTimer($time, function () use ($resolve) {
+ $resolve(null);
+ });
+ }, function () use (&$timer, $loop) {
+ // cancelling this promise will cancel the timer, clean the reference
+ // in order to avoid garbage references in call stack and then reject.
+ $loop->cancelTimer($timer);
+ $timer = null;
+
+ throw new \RuntimeException('Timer cancelled');
+ });
+}
+
+/**
+ * [Deprecated] Create a new promise that resolves in `$time` seconds with the `$time` as the fulfillment value.
+ *
+ * ```php
+ * React\Promise\Timer\resolve(1.5)->then(function ($time) {
+ * echo 'Thanks for waiting ' . $time . ' seconds' . PHP_EOL;
+ * });
+ * ```
+ *
+ * Internally, the given `$time` value will be used to start a timer that will
+ * resolve the promise once it triggers. This implies that if you pass a really
+ * small (or negative) value, it will still start a timer and will thus trigger
+ * at the earliest possible time in the future.
+ *
+ * This function takes an optional `LoopInterface|null $loop` parameter that can be used to
+ * pass the event loop instance to use. You can use a `null` value here in order to
+ * use the [default loop](https://github.com/reactphp/event-loop#loop). This value
+ * SHOULD NOT be given unless you're sure you want to explicitly use a given event
+ * loop instance.
+ *
+ * The returned promise is implemented in such a way that it can be cancelled
+ * when it is still pending. Cancelling a pending promise will reject its value
+ * with a `RuntimeException` and clean up any pending timers.
+ *
+ * ```php
+ * $timer = React\Promise\Timer\resolve(2.0);
+ *
+ * $timer->cancel();
+ * ```
+ *
+ * @param float $time
+ * @param ?LoopInterface $loop
+ * @return PromiseInterface<float, \RuntimeException>
+ * @deprecated 1.8.0 See `sleep()` instead
+ * @see sleep()
+ */
+function resolve($time, LoopInterface $loop = null)
+{
+ return sleep($time, $loop)->then(function() use ($time) {
+ return $time;
+ });
+}
+
+/**
+ * [Deprecated] Create a new promise which rejects in `$time` seconds with a `TimeoutException`.
+ *
+ * ```php
+ * React\Promise\Timer\reject(2.0)->then(null, function (React\Promise\Timer\TimeoutException $e) {
+ * echo 'Rejected after ' . $e->getTimeout() . ' seconds ' . PHP_EOL;
+ * });
+ * ```
+ *
+ * Internally, the given `$time` value will be used to start a timer that will
+ * reject the promise once it triggers. This implies that if you pass a really
+ * small (or negative) value, it will still start a timer and will thus trigger
+ * at the earliest possible time in the future.
+ *
+ * This function takes an optional `LoopInterface|null $loop` parameter that can be used to
+ * pass the event loop instance to use. You can use a `null` value here in order to
+ * use the [default loop](https://github.com/reactphp/event-loop#loop). This value
+ * SHOULD NOT be given unless you're sure you want to explicitly use a given event
+ * loop instance.
+ *
+ * The returned promise is implemented in such a way that it can be cancelled
+ * when it is still pending. Cancelling a pending promise will reject its value
+ * with a `RuntimeException` and clean up any pending timers.
+ *
+ * ```php
+ * $timer = React\Promise\Timer\reject(2.0);
+ *
+ * $timer->cancel();
+ * ```
+ *
+ * @param float $time
+ * @param LoopInterface $loop
+ * @return PromiseInterface<void, TimeoutException|\RuntimeException>
+ * @deprecated 1.8.0 See `sleep()` instead
+ * @see sleep()
+ */
+function reject($time, LoopInterface $loop = null)
+{
+ return sleep($time, $loop)->then(function () use ($time) {
+ throw new TimeoutException($time, 'Timer expired after ' . $time . ' seconds');
+ });
+}
diff --git a/vendor/react/promise-timer/src/functions_include.php b/vendor/react/promise-timer/src/functions_include.php
new file mode 100644
index 0000000..1d5673a
--- /dev/null
+++ b/vendor/react/promise-timer/src/functions_include.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace React\Promise\Timer;
+
+if (!function_exists('React\\Promise\\Timer\\timeout')) {
+ require __DIR__ . '/functions.php';
+}