Skip to content

Commit d1a9e96

Browse files
author
toby7002
committed
Fix some mistakes
1 parent 293912d commit d1a9e96

File tree

6 files changed

+58
-116
lines changed

6 files changed

+58
-116
lines changed

src/thebigcrafter/Hydrogen/Hydrogen.php

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,51 +17,43 @@
1717
use thebigcrafter\Hydrogen\future\FutureState;
1818
use thebigcrafter\Hydrogen\tasks\CheckUpdatesTask;
1919

20-
class Hydrogen {
20+
class Hydrogen
21+
{
2122

2223
/**
2324
* Notify if an update is available on Poggit.
2425
*/
25-
public static function checkForUpdates(Plugin $plugin) : void {
26+
public static function checkForUpdates(Plugin $plugin) : void
27+
{
2628
Server::getInstance()->getAsyncPool()->submitTask(new CheckUpdatesTask($plugin->getName(), $plugin->getDescription()->getVersion()));
2729
}
2830

2931
/**
3032
* Creates a new fiber asynchronously using the given closure, returning a Future that is completed with the
3133
* eventual return value of the passed function or will fail if the closure throws an exception.
32-
*
33-
* @template T
34-
*
35-
* @param \Closure(...):T $closure
36-
* @param mixed ...$args Arguments forwarded to the closure when starting the fiber.
37-
*
38-
* @return Future<T>
3934
*/
40-
public static function async(\Closure $closure, mixed ...$args) : Future
41-
{
42-
static $run = null;
35+
public static function async(\Closure $closure, mixed ...$args) : Future
36+
{
37+
static $run = null;
4338

44-
$run ??= static function (FutureState $state, \Closure $closure, array $args) : void {
45-
$s = $state;
46-
$c = $closure;
39+
$run ??= static function (FutureState $state, \Closure $closure, array $args) : void {
40+
$s = $state;
41+
$c = $closure;
4742

48-
/* Null function arguments so an exception thrown from the closure does not contain the FutureState object
49-
* in the stack trace, which would create a circular reference, preventing immediate garbage collection */
50-
$state = $closure = null;
43+
$state = $closure = null;
5144

52-
try {
53-
// Clear $args to allow garbage collection of arguments during fiber execution
54-
$s->complete($c(...$args, ...($args = [])));
55-
} catch (\Throwable $exception) {
56-
$s->error($exception);
57-
}
58-
};
45+
try {
46+
$s->complete($c(...$args, ...($args = [])));
47+
} catch (\Throwable $exception) {
48+
$s->error($exception);
49+
}
50+
};
5951

60-
$state = new FutureState();
52+
$state = new FutureState();
6153

62-
EventLoop::queue($run, $state, $closure, $args);
54+
EventLoop::queue($run, $state, $closure, $args);
6355

64-
return new Future($state);
65-
}
56+
return new Future($state);
57+
}
6658

6759
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Hydrogen.
5+
* (c) thebigcrafter <hello@thebigcrafter.xyz>
6+
* This source file is subject to the Apache-2.0 license that is bundled
7+
* with this source code in the file LICENSE.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace thebigcrafter\Hydrogen\exceptions;
13+
14+
class UnhandledFutureError extends \Error
15+
{
16+
public function __construct(\Throwable $previous, ?string $origin = null)
17+
{
18+
$message = 'Unhandled future: ' . $previous::class . ': "' . $previous->getMessage()
19+
. '"; Await the Future with Future::await() before the future is destroyed or use '
20+
. 'Future::ignore() to suppress this exception.';
21+
22+
if ($origin) {
23+
$message .= ' The future has been created at ' . $origin;
24+
} else {
25+
$message .= ' Enable assertions and set AMP_DEBUG=true in the process environment to track its origin.';
26+
}
27+
28+
parent::__construct($message, 0, $previous);
29+
}
30+
}

src/thebigcrafter/Hydrogen/future/Future.php

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,18 @@
1717
use thebigcrafter\Hydrogen\trait\ForbidSerialization;
1818
use function is_array;
1919

20-
/**
21-
* @template-covariant T
22-
*/
2320
final class Future
2421
{
2522
use ForbidCloning;
2623
use ForbidSerialization;
2724

2825
/**
2926
* Iterate over the given futures in completion order.
30-
*
31-
* @template Tk
32-
* @template Tv
33-
*
34-
* @param iterable<Tk, Future<Tv>> $futures
35-
* @param Cancellation|null $cancellation Optional cancellation.
36-
*
37-
* @return iterable<Tk, Future<Tv>>
3827
*/
3928
public static function iterate(iterable $futures, ?Cancellation $cancellation = null) : iterable
4029
{
4130
$iterator = new FutureIterator($cancellation);
4231

43-
// Directly iterate in case of an array, because there can't be suspensions during iteration
4432
if (is_array($futures)) {
4533
foreach ($futures as $key => $future) {
4634
if (!$future instanceof self) {
@@ -50,8 +38,6 @@ public static function iterate(iterable $futures, ?Cancellation $cancellation =
5038
}
5139
$iterator->complete();
5240
} else {
53-
// Use separate fiber for iteration over non-array, because not all items might be immediately available
54-
// while other futures are already completed.
5541
EventLoop::queue(static function () use ($futures, $iterator) : void {
5642
try {
5743
foreach ($futures as $key => $future) {
@@ -72,13 +58,6 @@ public static function iterate(iterable $futures, ?Cancellation $cancellation =
7258
}
7359
}
7460

75-
/**
76-
* @template Tv
77-
*
78-
* @param Tv $value
79-
*
80-
* @return Future<Tv>
81-
*/
8261
public static function complete(mixed $value = null) : self
8362
{
8463
$state = new FutureState();
@@ -99,21 +78,15 @@ public static function error(\Throwable $throwable) : self
9978
return new self($state);
10079
}
10180

102-
/** @var FutureState<T> */
10381
private readonly FutureState $state;
10482

105-
/**
106-
* @param FutureState<T> $state
107-
*
108-
* @internal Use {@see DeferredFuture} or {@see async()} to create and resolve a Future.
109-
*/
11083
public function __construct(FutureState $state)
11184
{
11285
$this->state = $state;
11386
}
11487

11588
/**
116-
* @return bool True if the operation has completed.
89+
* True if the operation has completed.
11790
*/
11891
public function isComplete() : bool
11992
{
@@ -122,8 +95,6 @@ public function isComplete() : bool
12295

12396
/**
12497
* Do not forward unhandled errors to the event loop handler.
125-
*
126-
* @return Future<T>
12798
*/
12899
public function ignore() : self
129100
{
@@ -135,14 +106,6 @@ public function ignore() : self
135106
/**
136107
* Attaches a callback that is invoked if this future completes. The returned future is completed with the return
137108
* value of the callback, or errors with an exception thrown from the callback.
138-
*
139-
* @psalm-suppress InvalidTemplateParam
140-
*
141-
* @template Tr
142-
*
143-
* @param \Closure(T):Tr $map
144-
*
145-
* @return Future<Tr>
146109
*/
147110
public function map(\Closure $map) : self
148111
{
@@ -168,12 +131,6 @@ public function map(\Closure $map) : self
168131
/**
169132
* Attaches a callback that is invoked if this future errors. The returned future is completed with the return
170133
* value of the callback, or errors with an exception thrown from the callback.
171-
*
172-
* @template Tr
173-
*
174-
* @param \Closure(\Throwable):Tr $catch
175-
*
176-
* @return Future<Tr>
177134
*/
178135
public function catch(\Closure $catch) : self
179136
{
@@ -199,10 +156,6 @@ public function catch(\Closure $catch) : self
199156
* Attaches a callback that is always invoked when the future is completed. The returned future resolves with the
200157
* same value as this future once the callback has finished execution. If the callback throws, the returned future
201158
* will error with the thrown exception.
202-
*
203-
* @param \Closure():void $finally
204-
*
205-
* @return Future<T>
206159
*/
207160
public function finally(\Closure $finally) : self
208161
{
@@ -229,8 +182,6 @@ public function finally(\Closure $finally) : self
229182
* Awaits the operation to complete.
230183
*
231184
* Throws an exception if the operation fails.
232-
*
233-
* @return T
234185
*/
235186
public function await(?Cancellation $cancellation = null) : mixed
236187
{

src/thebigcrafter/Hydrogen/future/FutureIterator.php

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,11 @@
1818
use thebigcrafter\Hydrogen\trait\ForbidSerialization;
1919
use function array_key_first;
2020

21-
/**
22-
* @template Tk
23-
* @template Tv
24-
*
25-
* @internal
26-
*/
27-
final class FutureIterator
21+
class FutureIterator
2822
{
2923
use ForbidCloning;
3024
use ForbidSerialization;
3125

32-
/** @var FutureIteratorQueue<Tk, Tv> */
3326
private readonly FutureIteratorQueue $queue;
3427

3528
private readonly Cancellation $cancellation;
@@ -51,11 +44,6 @@ public function __construct(?Cancellation $cancellation = null)
5144
});
5245
}
5346

54-
/**
55-
* @param FutureState<Tv> $state
56-
* @param Tk $key
57-
* @param Future<Tv> $future
58-
*/
5947
public function enqueue(FutureState $state, mixed $key, Future $future) : void
6048
{
6149
if ($this->complete) {
@@ -116,9 +104,6 @@ public function error(\Throwable $exception) : void
116104
}
117105
}
118106

119-
/**
120-
* @return null|array{Tk, Future<Tv>}
121-
*/
122107
public function consume() : ?array
123108
{
124109
if ($this->queue->suspension) {
@@ -134,7 +119,6 @@ public function consume() : ?array
134119

135120
$this->queue->suspension = EventLoop::getSuspension();
136121

137-
/** @var null|array{Tk, Future<Tv>} */
138122
return $this->queue->suspension->suspend();
139123
}
140124

@@ -143,7 +127,6 @@ public function consume() : ?array
143127

144128
unset($this->queue->items[$key]);
145129

146-
/** @var null|array{Tk, Future<Tv>} */
147130
return $item;
148131
}
149132

src/thebigcrafter/Hydrogen/future/FutureIteratorQueue.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@
1313

1414
use thebigcrafter\Hydrogen\eventLoop\Suspension;
1515

16-
final class FutureIteratorQueue
16+
class FutureIteratorQueue
1717
{
18-
/** @var list<array{Tk, Future<Tv>}> */
1918
public array $items = [];
2019

21-
/** @var array<string, FutureState<Tv>> */
2220
public array $pending = [];
2321

2422
public ?Suspension $suspension = null;

src/thebigcrafter/Hydrogen/future/FutureState.php

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
namespace thebigcrafter\Hydrogen\future;
1313

1414
use thebigcrafter\Hydrogen\EventLoop;
15+
use thebigcrafter\Hydrogen\exceptions\UnhandledFutureError;
1516

16-
final class FutureState
17+
class FutureState
1718
{
18-
// Static so they can be used as array keys
1919
private static string $nextId = 'a';
2020

2121
private bool $complete = false;
@@ -25,7 +25,6 @@ final class FutureState
2525
/** @var array<string, \Closure(?\Throwable, ?T, string): void> */
2626
private array $callbacks = [];
2727

28-
/** @var T|null */
2928
private mixed $result = null;
3029

3130
private ?\Throwable $throwable = null;
@@ -44,17 +43,12 @@ public function __destruct()
4443
* Registers a callback to be notified once the operation is complete or errored.
4544
*
4645
* The callback is invoked directly from the event loop context, so suspension within the callback is not possible.
47-
*
48-
* @param \Closure(?\Throwable, ?T, string): void $callback Callback invoked on error / successful completion of
49-
* the future.
50-
*
51-
* @return string Identifier that can be used to cancel interest for this future.
5246
*/
5347
public function subscribe(\Closure $callback) : string
5448
{
5549
$id = self::$nextId++;
5650

57-
$this->handled = true; // Even if unsubscribed later, consider the future handled.
51+
$this->handled = true;
5852

5953
if ($this->complete) {
6054
EventLoop::queue($callback, $this->throwable, $this->result, $id);
@@ -69,8 +63,6 @@ public function subscribe(\Closure $callback) : string
6963
* Cancels a subscription.
7064
*
7165
* Cancellations are advisory only. The callback might still be called if it is already queued for execution.
72-
*
73-
* @param string $id Identifier returned from subscribe()
7466
*/
7567
public function unsubscribe(string $id) : void
7668
{
@@ -79,8 +71,6 @@ public function unsubscribe(string $id) : void
7971

8072
/**
8173
* Completes the operation with a result value.
82-
*
83-
* @param T $result Result of the operation.
8474
*/
8575
public function complete(mixed $result) : void
8676
{
@@ -98,8 +88,6 @@ public function complete(mixed $result) : void
9888

9989
/**
10090
* Marks the operation as failed.
101-
*
102-
* @param \Throwable $throwable Throwable to indicate the error.
10391
*/
10492
public function error(\Throwable $throwable) : void
10593
{
@@ -112,7 +100,7 @@ public function error(\Throwable $throwable) : void
112100
}
113101

114102
/**
115-
* @return bool True if the operation has completed.
103+
* True if the operation has completed.
116104
*/
117105
public function isComplete() : bool
118106
{

0 commit comments

Comments
 (0)