Coroutine.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Engine;
  12. use ArrayObject;
  13. use Hyperf\Engine\Contract\CoroutineInterface;
  14. use Hyperf\Engine\Exception\CoroutineDestroyedException;
  15. use Hyperf\Engine\Exception\RunningInNonCoroutineException;
  16. use Hyperf\Engine\Exception\RuntimeException;
  17. use Swoole\Coroutine as SwooleCo;
  18. class Coroutine implements CoroutineInterface
  19. {
  20. /**
  21. * @var callable
  22. */
  23. private $callable;
  24. private ?int $id = null;
  25. public function __construct(callable $callable)
  26. {
  27. $this->callable = $callable;
  28. }
  29. public static function create(callable $callable, ...$data): static
  30. {
  31. $coroutine = new static($callable);
  32. $coroutine->execute(...$data);
  33. return $coroutine;
  34. }
  35. public function execute(...$data): static
  36. {
  37. $this->id = SwooleCo::create($this->callable, ...$data);
  38. return $this;
  39. }
  40. public function getId(): int
  41. {
  42. if (is_null($this->id)) {
  43. throw new RuntimeException('Coroutine was not be executed.');
  44. }
  45. return $this->id;
  46. }
  47. public static function id(): int
  48. {
  49. return SwooleCo::getCid();
  50. }
  51. public static function pid(?int $id = null): int
  52. {
  53. if ($id) {
  54. $cid = SwooleCo::getPcid($id);
  55. if ($cid === false) {
  56. throw new CoroutineDestroyedException(sprintf('Coroutine #%d has been destroyed.', $id));
  57. }
  58. } else {
  59. $cid = SwooleCo::getPcid();
  60. }
  61. if ($cid === false) {
  62. throw new RunningInNonCoroutineException('Non-Coroutine environment don\'t has parent coroutine id.');
  63. }
  64. return max(0, $cid);
  65. }
  66. public static function set(array $config): void
  67. {
  68. SwooleCo::set($config);
  69. }
  70. public static function getContextFor(?int $id = null): ?ArrayObject
  71. {
  72. if ($id === null) {
  73. return SwooleCo::getContext();
  74. }
  75. return SwooleCo::getContext($id);
  76. }
  77. public static function defer(callable $callable): void
  78. {
  79. SwooleCo::defer($callable);
  80. }
  81. /**
  82. * Yield the current coroutine.
  83. * @param mixed $data only Support Swow
  84. * @return bool
  85. */
  86. public static function yield(mixed $data = null): mixed
  87. {
  88. return SwooleCo::yield();
  89. }
  90. /**
  91. * Resume the coroutine by coroutine Id.
  92. * @param mixed $data only Support Swow
  93. * @return bool
  94. */
  95. public static function resumeById(int $id, mixed ...$data): mixed
  96. {
  97. return SwooleCo::resume($id);
  98. }
  99. /**
  100. * Get the coroutine stats.
  101. */
  102. public static function stats(): array
  103. {
  104. return SwooleCo::stats();
  105. }
  106. public static function exists(?int $id = null): bool
  107. {
  108. return SwooleCo::exists($id);
  109. }
  110. }