-
-
Save sovetski/0ccc12671dddafa5b3971a0f27da83cf to your computer and use it in GitHub Desktop.
Async PHP v2 (This is another attempt at Async PHP using stream socket pair capabilities.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| declare(strict_types=1); | |
| function async(Closure $task): Closure | |
| { | |
| static $resolved = []; | |
| static $id = 0; | |
| $id++; | |
| if (! extension_loaded('pcntl') || ! extension_loaded('posix')) { | |
| return fn () => $task($id); | |
| } | |
| [$parent, $child] = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP); | |
| $pid = pcntl_fork(); | |
| if ($pid === 0) { | |
| fclose($parent); | |
| $result = $task($id); | |
| fwrite($child, serialize($result)); | |
| fclose($child); | |
| exit(0); | |
| } | |
| return function () use ($pid, $id, $child, $parent, &$resolved) { | |
| if (isset($resolved[$id])) { | |
| return $resolved[$id]; | |
| } | |
| fclose($child); | |
| pcntl_waitpid($pid, $status); | |
| $serialized = fgets($parent); | |
| fclose($parent); | |
| return $resolved[$id] ??= unserialize($serialized); | |
| }; | |
| } | |
| function await(Closure|array $tasks): mixed | |
| { | |
| if (! is_array($tasks)) { | |
| return $tasks(); | |
| } | |
| return array_map( | |
| fn (Closure $task): mixed => $task(), $tasks, | |
| ); | |
| } | |
| $start = microtime(true); | |
| $hello = async(function (int $id) { | |
| echo "Running task {$id}\n"; | |
| sleep(2); | |
| return "Hello from task {$id}"; | |
| }); | |
| $task2 = async(function (int $id) { | |
| echo "Running task {$id}\n"; | |
| sleep(3); | |
| return "Hello from task {$id}"; | |
| }); | |
| var_dump(await([$hello, $task2])); | |
| $end = microtime(true); | |
| echo $end - $start; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment