Menu
Reference
- Manticore\Ds
- Async
- Classes
- AggregateError
- CancellationToken
- CancelledException
- Channel
- ChannelClosedException
- Context
- DeadlockException
- Mutex
- Once
- Pool
- Received
- SelectCase
- Selected
- Semaphore
- Settled
- Task
- TaskGroup
- TimeoutException
- Functions
- async()
- awaitAll()
- awaitAllSettled()
- awaitAny()
- channel()
- delay()
- dump()
- dumpOn()
- failure()
- group()
- mapConcurrent()
- mapSettled()
- readFile()
- select()
- selectNow()
- selectWithin()
- shield()
- shutdownOn()
- spawn()
- stats()
- timeout()
- watchdog()
- writeFile()
- Http
- Http\WebSocket
- Buffer
- Process
- Io\Poll
- Manticore\Sapi
- Ffi
Context
final class Context
The ambient view of the scope the calling task is in: cancellation, the effective deadline, and scoped values.
These are static methods that answer for the calling task, so a helper deep in the call stack can check for cancellation or read the request id without being passed anything. Outside async() there is no scope: isCancelled() is false, deadline(), remaining() and value() return null.
Context::withValue('request-id', $id, function () {
spawn(fn() => log(Context::value('request-id')));
});Example
use Async\Context;
use function Async\async;
use function Async\awaitAll;
use function Async\spawn;
use function Async\timeout;
async(function () {
// Values are scoped: every task spawned inside sees them, nothing outside does.
Context::withValue('request-id', 'r-42', function () {
$t = spawn(fn() => Context::value('request-id'));
echo "inside: ", $t->await(), "\n";
});
var_dump(Context::value('request-id'));
// No deadline means unbounded.
var_dump(Context::remaining());
// A timeout() scope publishes its deadline.
timeout(5.0, function () {
$left = Context::remaining();
echo "deadline set: ", ($left !== null && $left > 0.0 && $left <= 5.0) ? "yes" : "no", "\n";
echo "cancelled: ", Context::isCancelled() ? "yes" : "no", "\n";
});
});Output
inside: r-42
NULL
NULL
deadline set: yes
cancelled: noSee also: CancellationToken, timeout
Methods
currentScope() | The innermost scope open in the calling task. |
token() | The cancellation handle of the scope the calling task is in. |
isCancelled() | Whether the calling task's scope, or any ancestor, has been cancelled. |
throwIfCancelled() | Cancellation checkpoint: throw if the calling task's scope was cancelled. |
deadline() | The effective deadline of the calling task as a unix time. |
remaining() | Seconds left before the effective deadline, never negative. |
value() | A value bound by an enclosing withValue() scope. |
withValue() | Bind $key to $value for the duration of $body. |
currentScope()#source
static function currentScope(): ?TaskGroup
The innermost scope open in the calling task.
Safe to call anywhere: it never builds the engine.
Returns
?TaskGroup — the scope, or null outside async()
token()#source
static function token(): CancellationToken
The cancellation handle of the scope the calling task is in.
Returns
CancellationToken — a read-only view of the current scope
Throws
- \LogicException
- outside
async(), where there is no scope
See also: TaskGroup::token
isCancelled()#source
static function isCancelled(): bool
Whether the calling task's scope, or any ancestor, has been cancelled.
Returns
bool — true once cancellation was requested; false outside async()
throwIfCancelled()#source
static function throwIfCancelled(): void
Cancellation checkpoint: throw if the calling task's scope was cancelled.
Call it at loop heads in long CPU-bound tasks, which never reach a suspend point where cancellation would otherwise be delivered.
Throws
- CancelledException
- when the scope was cancelled
deadline()#source
static function deadline(): ?float
The effective deadline of the calling task as a unix time.
The earliest deadline of the enclosing timeout() scopes; a nested scope can only tighten it.
Returns
?float — unix timestamp, or null when there is no deadline
See also: timeout
remaining()#source
static function remaining(): ?float
Seconds left before the effective deadline, never negative.
Returns
?float — seconds remaining, or null when unbounded
Example
use Async\Context;
use function Async\async;
use function Async\awaitAll;
use function Async\spawn;
use function Async\timeout;
async(function () {
// Values are scoped: every task spawned inside sees them, nothing outside does.
Context::withValue('request-id', 'r-42', function () {
$t = spawn(fn() => Context::value('request-id'));
echo "inside: ", $t->await(), "\n";
});
var_dump(Context::value('request-id'));
// No deadline means unbounded.
var_dump(Context::remaining());
// A timeout() scope publishes its deadline.
timeout(5.0, function () {
$left = Context::remaining();
echo "deadline set: ", ($left !== null && $left > 0.0 && $left <= 5.0) ? "yes" : "no", "\n";
echo "cancelled: ", Context::isCancelled() ? "yes" : "no", "\n";
});
});Output
inside: r-42
NULL
NULL
deadline set: yes
cancelled: novalue()#source
static function value(string $key): mixed
A value bound by an enclosing withValue() scope.
The request-id or correlation-id carrier: every task spawned inside the binding scope sees the value, nothing outside does. An inner binding shadows an outer one.
Parameters
$keystring- the name the value was bound under
Returns
mixed — the bound value, or null when unbound
Example
use Async\Context;
use function Async\async;
use function Async\awaitAll;
use function Async\spawn;
use function Async\timeout;
async(function () {
// Values are scoped: every task spawned inside sees them, nothing outside does.
Context::withValue('request-id', 'r-42', function () {
$t = spawn(fn() => Context::value('request-id'));
echo "inside: ", $t->await(), "\n";
});
var_dump(Context::value('request-id'));
// No deadline means unbounded.
var_dump(Context::remaining());
// A timeout() scope publishes its deadline.
timeout(5.0, function () {
$left = Context::remaining();
echo "deadline set: ", ($left !== null && $left > 0.0 && $left <= 5.0) ? "yes" : "no", "\n";
echo "cancelled: ", Context::isCancelled() ? "yes" : "no", "\n";
});
});Output
inside: r-42
NULL
NULL
deadline set: yes
cancelled: noSee also: withValue
withValue()#source
static function withValue(string $key, mixed $value, callable $body): mixed
Bind $key to $value for the duration of $body.
$body runs in a scope of its own, so it is joined like any other scope: every task it spawns finishes before withValue() returns.
Parameters
$keystring- the name to bind
$valuemixed- the value to bind
$bodycallable- called with the new
TaskGroup
Returns
mixed — the value returned by $body
Example
use Async\Context;
use function Async\async;
use function Async\awaitAll;
use function Async\spawn;
use function Async\timeout;
async(function () {
// Values are scoped: every task spawned inside sees them, nothing outside does.
Context::withValue('request-id', 'r-42', function () {
$t = spawn(fn() => Context::value('request-id'));
echo "inside: ", $t->await(), "\n";
});
var_dump(Context::value('request-id'));
// No deadline means unbounded.
var_dump(Context::remaining());
// A timeout() scope publishes its deadline.
timeout(5.0, function () {
$left = Context::remaining();
echo "deadline set: ", ($left !== null && $left > 0.0 && $left <= 5.0) ? "yes" : "no", "\n";
echo "cancelled: ", Context::isCancelled() ? "yes" : "no", "\n";
});
});Output
inside: r-42
NULL
NULL
deadline set: yes
cancelled: noSee also: value