Coroutine.php
2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\Utils;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Engine\Coroutine as Co;
use Hyperf\Engine\Exception\CoroutineDestroyedException;
use Hyperf\Engine\Exception\RunningInNonCoroutineException;
use Hyperf\ExceptionHandler\Formatter\FormatterInterface;
use Psr\Log\LoggerInterface;
use Throwable;
class Coroutine
{
/**
* Returns the current coroutine ID.
* Returns -1 when running in non-coroutine context.
*/
public static function id(): int
{
return Co::id();
}
public static function defer(callable $callable)
{
Co::defer($callable);
}
public static function sleep(float $seconds)
{
usleep(intval($seconds * 1000 * 1000));
}
/**
* Returns the parent coroutine ID.
* Returns 0 when running in the top level coroutine.
* @throws RunningInNonCoroutineException when running in non-coroutine context
* @throws CoroutineDestroyedException when the coroutine has been destroyed
*/
public static function parentId(?int $coroutineId = null): int
{
return Co::pid($coroutineId);
}
/**
* @return int Returns the coroutine ID of the coroutine just created.
* Returns -1 when coroutine create failed.
*/
public static function create(callable $callable): int
{
$coroutine = Co::create(function () use ($callable) {
try {
call($callable);
} catch (Throwable $throwable) {
if (ApplicationContext::hasContainer()) {
$container = ApplicationContext::getContainer();
if ($container->has(StdoutLoggerInterface::class)) {
/* @var LoggerInterface $logger */
$logger = $container->get(StdoutLoggerInterface::class);
/* @var FormatterInterface $formatter */
if ($container->has(FormatterInterface::class)) {
$formatter = $container->get(FormatterInterface::class);
$logger->warning($formatter->format($throwable));
} else {
$logger->warning(sprintf('Uncaptured exception[%s] detected in %s::%d.', get_class($throwable), $throwable->getFile(), $throwable->getLine()));
}
}
}
}
});
try {
return $coroutine->getId();
} catch (\Throwable $exception) {
return -1;
}
}
public static function inCoroutine(): bool
{
return Co::id() > 0;
}
}