Skip to content

Commit cd3bbd1

Browse files
authored
Add GreenThread and Clean some code!
- GreenThread about here: https://github.com/VennDev/Vapm#green-thread
1 parent 5a8eae7 commit cd3bbd1

14 files changed

+432
-3
lines changed

src/vennv/vapm/Async.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
namespace vennv\vapm;
2828

2929
use Throwable;
30+
use function is_callable;
3031

3132
final class Async implements AsyncInterface
3233
{

src/vennv/vapm/EventLoop.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
namespace vennv\vapm;
2828

2929
use Throwable;
30+
use function count;
31+
use const PHP_INT_MAX;
3032

3133
class EventLoop implements EventLoopInterface
3234
{
@@ -125,6 +127,11 @@ private static function clearGarbage(): void
125127
*/
126128
protected static function run(): void
127129
{
130+
if (count(GreenThread::getFibers()) > 0)
131+
{
132+
GreenThread::run();
133+
}
134+
128135
foreach (self::$queues as $id => $promise)
129136
{
130137
$fiber = $promise->getFiber();
@@ -163,7 +170,7 @@ protected static function run(): void
163170
*/
164171
protected static function runSingle(): void
165172
{
166-
while (count(self::$queues) > 0 || count(MicroTask::getTasks()) > 0 || count(MacroTask::getTasks()) > 0)
173+
while (count(self::$queues) > 0 || count(MicroTask::getTasks()) > 0 || count(MacroTask::getTasks()) > 0 || count(GreenThread::getFibers()) > 0)
167174
{
168175
self::run();
169176
}

src/vennv/vapm/FiberManager.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
use Fiber;
3030
use Throwable;
31+
use function is_null;
3132

3233
final class FiberManager
3334
{

src/vennv/vapm/GreenThread.php

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?php
2+
3+
/*
4+
* Copyright (c) 2023 VennV
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
declare(strict_types = 1);
26+
27+
namespace vennv\vapm;
28+
29+
use Fiber;
30+
use Throwable;
31+
32+
final class GreenThread implements GreenThreadInterface
33+
{
34+
35+
/**
36+
* @var array<int, string|int>
37+
*/
38+
private static array $names = [];
39+
40+
/**
41+
* @var array<int, Fiber>
42+
*/
43+
private static array $fibers = [];
44+
45+
/**
46+
* @var array<int, array<int, mixed>>
47+
*/
48+
private static array $params = [];
49+
50+
/**
51+
* @var array<string|int, mixed>
52+
*/
53+
private static array $outputs = [];
54+
55+
/**
56+
* @var array<string|int, StatusThread>
57+
*/
58+
private static array $status = [];
59+
60+
/**
61+
* @param string|int $name
62+
* @param callable $callback
63+
* @param array<int, mixed> $params
64+
*/
65+
public static function register(string|int $name, callable $callback, array $params): void
66+
{
67+
if (isset(self::$outputs[$name]))
68+
{
69+
unset(self::$outputs[$name]);
70+
}
71+
72+
self::$names[] = $name;
73+
self::$fibers[] = new Fiber($callback);
74+
self::$params[] = $params;
75+
self::$status[$name] = new StatusThread();
76+
}
77+
78+
/**
79+
* @throws Throwable
80+
*/
81+
public static function run(): void
82+
{
83+
foreach (self::$fibers as $i => $fiber)
84+
{
85+
if (!self::$status[self::$names[$i]]->canWakeUp())
86+
{
87+
continue;
88+
}
89+
90+
$name = self::$names[$i];
91+
92+
try
93+
{
94+
if (!$fiber->isStarted())
95+
{
96+
$fiber->start(...self::$params[$i]);
97+
}
98+
elseif ($fiber->isTerminated())
99+
{
100+
self::$outputs[$name] = $fiber->getReturn();
101+
unset(self::$fibers[$i]);
102+
}
103+
elseif ($fiber->isSuspended())
104+
{
105+
$fiber->resume();
106+
}
107+
}
108+
catch (Throwable $e)
109+
{
110+
self::$outputs[$name] = $e;
111+
}
112+
}
113+
}
114+
115+
public static function clear(): void
116+
{
117+
self::$names = [];
118+
self::$fibers = [];
119+
self::$params = [];
120+
}
121+
122+
/**
123+
* @return array<int, string|int>
124+
*/
125+
public static function getNames(): array
126+
{
127+
return self::$names;
128+
}
129+
130+
/**
131+
* @return array<int, Fiber>
132+
*/
133+
public static function getFibers(): array
134+
{
135+
return self::$fibers;
136+
}
137+
138+
/**
139+
* @return array<int, array<int, mixed>>
140+
*/
141+
public static function getParams(): array
142+
{
143+
return self::$params;
144+
}
145+
146+
/**
147+
* @return array<string|int, mixed>
148+
*/
149+
public static function getOutputs(): array
150+
{
151+
return self::$outputs;
152+
}
153+
154+
/**
155+
* @param string|int $name
156+
* @return mixed
157+
*/
158+
public static function getOutput(string|int $name): mixed
159+
{
160+
return self::$outputs[$name];
161+
}
162+
163+
/**
164+
* @throws Throwable
165+
*/
166+
public static function sleep(string $name, int $seconds): void
167+
{
168+
self::$status[$name]->sleep($seconds);
169+
170+
$fiberCurrent = Fiber::getCurrent();
171+
172+
if ($fiberCurrent !== null)
173+
{
174+
$fiberCurrent::suspend();
175+
}
176+
}
177+
178+
public static function getStatus(string|int $name): StatusThread|null
179+
{
180+
return self::$status[$name] ?? null;
181+
}
182+
183+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
/*
4+
* Copyright (c) 2023 VennV
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
declare(strict_types = 1);
26+
27+
namespace vennv\vapm;
28+
29+
use Fiber;
30+
use Throwable;
31+
32+
interface GreenThreadInterface
33+
{
34+
35+
/**
36+
* @param string|int $name
37+
* @param callable $callback
38+
* @param array<int, mixed> $params
39+
*
40+
* This method is used to register a green thread.
41+
*/
42+
public static function register(string|int $name, callable $callback, array $params): void;
43+
44+
/**
45+
* @throws Throwable
46+
*/
47+
public static function run(): void;
48+
49+
/**
50+
* This method is used to clear the data of the green threads.
51+
*/
52+
public static function clear(): void;
53+
54+
/**
55+
* @return array<int, string|int>
56+
*
57+
* This method is used to get the names of the green threads.
58+
*/
59+
public static function getNames(): array;
60+
61+
/**
62+
* @return array<int, Fiber>
63+
*
64+
* This method is used to get the fibers of the green threads.
65+
*/
66+
public static function getFibers(): array;
67+
68+
/**
69+
* @return array<int, array<int, mixed>>
70+
*
71+
* This method is used to get the params of the green threads.
72+
*/
73+
public static function getParams(): array;
74+
75+
/**
76+
* @return array<string|int, mixed>
77+
*
78+
* This method is used to get the outputs of the green threads.
79+
*/
80+
public static function getOutputs(): array;
81+
82+
/**
83+
* @param string|int $name
84+
* @return mixed
85+
*
86+
* This method is used to get the output of a green thread.
87+
*/
88+
public static function getOutput(string|int $name): mixed;
89+
90+
/**
91+
* @throws Throwable
92+
*/
93+
public static function sleep(string $name, int $seconds): void;
94+
95+
/**
96+
* @param string|int $name
97+
* @return StatusThread|null
98+
*
99+
* This method is used to get the status of a green thread.
100+
*/
101+
public static function getStatus(string|int $name): StatusThread|null;
102+
103+
}

src/vennv/vapm/Info.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
class Info
3030
{
3131

32-
public const VERSION = "1.5.0";
32+
public const VERSION = "1.5.7";
3333

3434
public const AUTHOR = "VennV";
3535

src/vennv/vapm/MacroTask.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
namespace vennv\vapm;
2828

29+
use const PHP_INT_MAX;
30+
2931
final class MacroTask
3032
{
3133

src/vennv/vapm/MicroTask.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
namespace vennv\vapm;
2828

2929
use Throwable;
30+
use function microtime;
3031

3132
final class MicroTask
3233
{

src/vennv/vapm/Promise.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828

2929
use Fiber;
3030
use Throwable;
31+
use function count;
32+
use function microtime;
33+
use function is_callable;
34+
use function call_user_func;
3135

3236
final class Promise implements PromiseInterface
3337
{

src/vennv/vapm/SampleMacro.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
namespace vennv\vapm;
2828

29+
use function call_user_func;
30+
use function microtime;
31+
2932
final class SampleMacro implements SampleMacroInterface
3033
{
3134

0 commit comments

Comments
 (0)