Created
January 10, 2024 08:51
-
-
Save diloabininyeri/0f2c28a4c2b91ff1a0d34ea128dd9086 to your computer and use it in GitHub Desktop.
php async promise
This file contains 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
class Parallel | |
{ | |
private array $threads = []; | |
private array $process = []; | |
public function add(PromiseInterface $promise): self | |
{ | |
$this->threads[] = $promise; | |
return $this; | |
} | |
public function run(): void | |
{ | |
foreach ($this->threads as $thread) { | |
$descriptors = [ | |
0 => ['pipe', 'r'], // stdin | |
1 => ['pipe', 'w'], // stdout | |
2 => ['pipe', 'w'], // stderr | |
]; | |
$process = proc_open('php', $descriptors, $pipes); | |
if (is_resource($process)) { | |
fwrite($pipes[0], $this->generatePhpCode($thread)); | |
fclose($pipes[0]); | |
fclose($pipes[2]); | |
$this->process [] = [ | |
'pipe' => $pipes[1], | |
'process' => $process, | |
'thread' => $thread | |
]; | |
} | |
} | |
} | |
/*** | |
* @return void | |
*/ | |
public function wait(): void | |
{ | |
while (!empty($this->process)) { | |
foreach ($this->process as $key => $value) { | |
[ | |
'pipe' => $pipe, | |
'process' => $process, | |
'thread' => $thread | |
] = $value; | |
if (is_resource($process)) { | |
$status = proc_get_status($process); | |
if ($status['running']) { | |
continue; | |
} | |
/** | |
* @var PromiseInterface $thread | |
*/ | |
$thread->then(stream_get_contents($pipe)); | |
echo PHP_EOL; | |
proc_close($process); | |
unset($this->process[$key]); | |
} | |
} | |
} | |
} | |
/*** | |
* @param PromiseInterface $promise | |
* @return string | |
*/ | |
private function generatePhpCode(PromiseInterface $promise): string | |
{ | |
$serialize=serialize($promise); | |
return "<?php require_once 'vendor/autoload.php';\$closure = unserialize('$serialize');echo \$closure(); ?>"; | |
} | |
} |
This file contains 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
interface PromiseInterface | |
{ | |
public function then(mixed $value); | |
public function __invoke(); | |
} |
This file contains 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
readonly class PromiseOne implements PromiseInterface | |
{ | |
public function __construct(private int $id) | |
{ | |
} | |
#[\Override] | |
public function then(mixed $value) | |
{ | |
echo $value; | |
} | |
public function __invoke() | |
{ | |
sleep(1); | |
return $this->id; | |
} | |
} |
This file contains 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
$parallel = new parallel(); | |
$parallel | |
->add(new PromiseOne(1)) | |
->add(new PromiseOne(2)) | |
->add(new PromiseOne(3)) | |
->add(new PromiseOne(4)) | |
->add(new PromiseOne(5)) | |
->add(new PromiseOne(6)) | |
->add(new PromiseOne(7)) | |
->add(new PromiseOne(8)); | |
$parallel->run(); | |
$parallel->wait(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment