# BoundedScope
I tried to refine the BoundedScope
class to its logical completeness,
considering your feedback.
However, I no longer like it because it now resembles an advanced
ComposeFuture
or BoundedFuture
(I'm not even sure which one).
There is no doubt that such functionality is needed, but I have concerns
about the design.
It seems better to implement BoundedFuture
separately (placing it in a
dedicated RFC) and incorporate this logic there, while BoundedScope
might
not be necessary at all.
Essentially, the code using BoundedScope
could be replaced with:
```php
$scope = new Scope();
$future = BoundedFuture();
try {
await $future;
} finally {
$scope->dispose();
}
```
On the other hand, a method like spawnAndProlong
could be useful if there
is a need to implement a pattern where the Scope
remains alive as long as
at least one task is active.
But is this case significant enough to keep it? I'm not sure.
I need some time to process this.
In the meantime, I'll show you the draft I came up with.
#### BoundedScope
The BoundedScope
class is designed to create explicit constraints
that will be applied to all coroutines spawned within the specified Scope.
The BoundedScope
class implements the following pattern:
```php
$scope = new Scope();
$constraints = new Future();
$scope->spawn(function () use($constraints) {
try {
await $constraints;
} finally {
\Async\currentScope()->cancel();
}
});
```
Here, $constraints
is an object implementing the Awaitable
interface.
Once it completes, the Scope
will be terminated, and all associated
resources will be released.
| Method | Description
|
|----------------------------------------|-------------------------------------------------------------------------------------------------------------|
| defineTimeout(int $milliseconds)
| Define a specified timeout,
automatically canceling coroutines when the time expires.
|
| spawnAndBound(callable $coroutine)
| Spawns a coroutine and
restricts the lifetime of the entire Scope to match the coroutine’s
lifetime. |
| spawnAndProlong(callable $coroutine)
| Spawns a coroutine and
extends the lifetime of the entire Scope to match the coroutine’s
lifetime. |
| boundedBy(Awaitable $constraint)
| Limits the scope’s lifetime
based on a **Cancellation token, Future, or another coroutine's
lifetime**. |
| prolongedBy(Awaitable $constraint)
| Extends the scope’s
lifetime based on a **Cancellation token, Future, or another
coroutine's lifetime**. |
```php
$scope = new BoundedScope();
$scope->defineTimeout(1000);
$scope->spawnAndBound(function() {
sleep(2);
echo "Task 1\n";
});
await $scope;
```
##### Prolong and Bound triggers
The BoundedScope
class operates with two types of triggers:
- **Bound trigger** – limits execution time by the minimum boundary..
- **Prolong trigger** – limits execution time by the maximum boundary.
For the **Prolong** trigger to execute, all **Prolong** objects must
be completed.
For the **Bound** trigger to execute, at least one **Bound** object
must be completed.
The Scope
will terminate as soon as either the **Prolong** or
**Bound** trigger is executed.
##### defineTimeout
The defineTimeout
method sets a global timeout for all coroutines
belonging to a Scope
.
The method initializes a single internal timer, which starts when
defineTimeout
is called.
When the timer expires, the Scope::cancel()
method is invoked.
The defineTimeout
method can only be called once; a repeated call
will throw an exception.
##### spawnAndBound / spawnAndProlong
spawnAndBound
creates a coroutine and limits its execution time to
the current Scope
.
The method can be called multiple times. In this case, the Scope
will not exist longer than
the lifetime of the shortest coroutine.
spawnAndProlong
creates a coroutine and extends the lifetime of the
current Scope
to match the coroutine's lifetime.
##### boundedBy / prolongedBy
The boundedBy
method allows limiting the lifetime of a Scope
by explicitly
specifying an object that implements the Awaitable
interface.
The Awaitable
interface is inherited by classes such as Coroutine
and Scope
.
Additionally, classes like Future
and Cancellation
,
which are not part of this RFC, can also implement the Awaitable
interface.