1
0
mirror of https://github.com/danog/amp.git synced 2024-12-02 17:37:50 +01:00

Update cancellation docs

This commit is contained in:
Niklas Keller 2021-12-02 23:45:45 +01:00
parent 19937d75d0
commit d20f07acee

View File

@ -1,28 +1,38 @@
--- ---
layout: docs layout: docs title: Cancellation permalink: /cancellation/
title: Cancellation
permalink: /cancellation/
--- ---
Amp provides primitives to allow the cancellation of operations, namely `CancellationTokenSource` and `CancellationToken`. Amp provides a `Cancellation` primitive to allow the cancellation of operations.
```php ```php
$tokenSource = new CancellationTokenSource; request("...", new Amp\TimeoutCancellation(30));
$promise = asyncRequest("...", $tokenSource->getToken());
Loop::delay(1000, function () use ($tokenSource) {
$tokenSource->cancel();
});
$result = yield $promise;
``` ```
Every operation that supports cancellation accepts an instance of `CancellationToken` as (optional) argument. Within a coroutine, `$token->throwIfRequested()` can be used to fail the operation with a `CancelledException`. As `$token` is often an optional parameter and might be `null`, these calls need to be guared with a `if ($token)` or similar check. Instead of doing so, it's often easier to simply set the token to `$token = $token ?? new NullCancellationToken` at the beginning of the method. ```php
$deferredCancellation = new Amp\DeferredCancellation();
Loop::onSignal(SIG_INT, function () use ($deferredCancellation) {
$deferredCancellation->cancel();
});
While `throwIfRequested()` works well within coroutines, some operations might want to subscribe with a callback instead. They can do so using `CancellationToken::subscribe()` to subscribe any cancellation requests that might happen. request("...", $deferredCancellation->getCancellation());
```
If the operation consists of any sub-operations that support cancellation, it passes that same `CancellationToken` instance down to these sub-operations. Every operation that supports cancellation accepts an instance of `Cancellation` as (optional)
argument. `$cancellation->throwIfRequested()` can be used to fail the operation with a `CancelledException`.
As `$cancellation` is often an optional parameter and might be `null`, these calls need to be guarded with
a `if ($cancellation)` or similar check. Instead of doing so, it's often easier to simply set the token
to `$cancellation ??= new NullCancellationToken` at the beginning of the method.
The original caller creates a `CancellationToken` by creating an instance of `CancellationTokenSource` and passing `$cancellationTokenSource->getToken()` to the operation as shown in the above example. Only the original caller has access to the `CancellationTokenSource` and can cancel the operation using `CancellationTokenSource::cancel()`, similar to the way it works with `Deferred` and `Promise`. While `throwIfRequested()` works well, some operations might want to subscribe with a callback instead. They can do so
using `Cancellation::subscribe()` to subscribe any cancellation requests that might happen.
If the operation consists of any sub-operations that support cancellation, it passes that same `Cancellation`
instance down to these sub-operations.
The original caller creates a `Cancellation` by creating an instance of `DeferredCancellation` and
passing `$deferred->getCancellation()` to the operation as shown in the above example, or using one of the other
implementations of `Cancellation`, such as `TimeoutCancellation`. Only the original caller has access to
the `DeferredCancellation` and can cancel the operation using `DeferredCancellation::cancel()`, similar to the way it
works with `DeferredFuture` and `Future`.
{:.note} {:.note}
> Cancellations are advisory only. A DNS resolver might ignore cancellation requests after the query has been sent as the response has to be processed anyway and can still be cached. An HTTP client might continue a nearly finished HTTP request to reuse the connection, but might abort a chunked encoding response as it cannot know whether continuing is actually cheaper than aborting. > Cancellations are advisory only. A DNS resolver might ignore cancellation requests after the query has been sent as the response has to be processed anyway and can still be cached. An HTTP client might continue a nearly finished HTTP request to reuse the connection, but might abort a chunked encoding response as it cannot know whether continuing is actually cheaper than aborting.