-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 79078e6
Showing
24 changed files
with
904 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
vendor | ||
bin | ||
composer.lock | ||
tmp/* |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<?php | ||
|
||
namespace EProcess\Adapter; | ||
|
||
use EProcess\Behaviour\UniversalSerializer; | ||
use EProcess\MessengerFactory; | ||
|
||
use React\ChildProcess\Process; | ||
use React\EventLoop\LoopInterface; | ||
use Symfony\Component\Process\PhpExecutableFinder; | ||
|
||
class ChildProcess | ||
{ | ||
use UniversalSerializer; | ||
|
||
private $script = <<<PHP | ||
<?php | ||
require_once '%s'; | ||
set_time_limit(0); | ||
use EProcess\MessengerFactory; | ||
use EProcess\Application\ApplicationFactory; | ||
use React\EventLoop\Factory; | ||
\$loop = Factory::create(); | ||
\$messenger = MessengerFactory::client( | ||
'%s', | ||
\$loop | ||
); | ||
\$application = ApplicationFactory::create('%s'); | ||
\$application->messenger(\$messenger); | ||
\$application->loop(\$loop); | ||
\$application->data(\$application->unserialize(base64_decode('%s'))); | ||
\$messenger->emit('initialized', true); | ||
try { | ||
\$application->run(); | ||
\$loop->run(); | ||
} catch (\Exception \$e) { | ||
echo \$e; | ||
} | ||
PHP; | ||
|
||
private $loop; | ||
private $process; | ||
private $executableFinder; | ||
|
||
public function __construct(LoopInterface $loop) | ||
{ | ||
$this->loop = $loop; | ||
$this->executableFinder = new PhpExecutableFinder(); | ||
} | ||
|
||
public function create($class, array $data = []) | ||
{ | ||
if (false === $php = $this->executableFinder->find()) { | ||
throw new \RuntimeException('Unable to find the PHP executable.'); | ||
} | ||
|
||
$node = uniqid('thread_'); | ||
$unix = sprintf('unix://tmp/%s.sock', $node); | ||
|
||
$messenger = MessengerFactory::server($unix, $this->loop); | ||
|
||
$file = sprintf(__DIR__ . '/../../tmp/%s.php', $node); | ||
|
||
file_put_contents($file, sprintf( | ||
$this->script, | ||
EPROCESS_AUTOLOAD, | ||
$unix, | ||
$class, | ||
base64_encode($this->serialize($data)) | ||
)); | ||
|
||
$this->process = new Process(sprintf('exec %s %s', $php, realpath($file))); | ||
$this->process->start($this->loop); | ||
|
||
$this->loop->addTimer(5, function() use ($file) { | ||
unlink($file); | ||
}); | ||
|
||
$this->process->stdout->on('data', function($data) { | ||
echo $data; | ||
}); | ||
|
||
$this->process->stderr->on('data', function($data) { | ||
echo $data; | ||
}); | ||
|
||
register_shutdown_function(function() use ($unix) { | ||
unlink($unix); | ||
}); | ||
|
||
return $messenger; | ||
} | ||
|
||
public function kill() | ||
{ | ||
$this->process->close(); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
namespace EProcess\Adapter; | ||
|
||
use EProcess\MessengerFactory; | ||
use React\EventLoop\LoopInterface; | ||
|
||
class PThreads | ||
{ | ||
private $loop; | ||
private $process; | ||
|
||
public function __construct(LoopInterface $loop) | ||
{ | ||
$this->loop = $loop; | ||
} | ||
|
||
public function create($class, array $data = []) | ||
{ | ||
$node = uniqid('thread_'); | ||
$unix = sprintf('unix://tmp/%s.sock', $node); | ||
|
||
$messenger = MessengerFactory::server($unix, $this->loop); | ||
|
||
$this->process = new Thread($unix, $class, $data); | ||
$this->process->start(PTHREADS_INHERIT_NONE); | ||
|
||
return $messenger; | ||
} | ||
|
||
public function kill() | ||
{ | ||
$this->process->kill(); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?php | ||
|
||
namespace EProcess\Adapter; | ||
|
||
use EProcess\Behaviour\UniversalSerializer; | ||
use Symfony\Component\Process\PhpProcess; | ||
use React\EventLoop\LoopInterface; | ||
use EProcess\MessengerFactory; | ||
|
||
class SymfonyProcess | ||
{ | ||
use UniversalSerializer; | ||
|
||
private $script = <<<PHP | ||
<?php | ||
require_once '%s'; | ||
set_time_limit(0); | ||
use EProcess\MessengerFactory; | ||
use EProcess\Application\ApplicationFactory; | ||
use React\EventLoop\Factory; | ||
\$loop = Factory::create(); | ||
\$messenger = MessengerFactory::client( | ||
'%s', | ||
\$loop | ||
); | ||
\$application = ApplicationFactory::create('%s'); | ||
\$application->messenger(\$messenger); | ||
\$application->loop(\$loop); | ||
\$application->data(\$application->unserialize(base64_decode('%s'))); | ||
\$messenger->emit('initialized', true); | ||
try { | ||
\$application->run(); | ||
\$loop->run(); | ||
} catch (\Exception \$e) { | ||
echo \$e; | ||
} | ||
PHP; | ||
|
||
private $loop; | ||
private $process; | ||
|
||
public function __construct(LoopInterface $loop) | ||
{ | ||
$this->loop = $loop; | ||
} | ||
|
||
public function create($class, array $data = []) | ||
{ | ||
$node = uniqid('thread_'); | ||
$unix = sprintf('unix://app/cache/%s.sock', $node); | ||
|
||
$messenger = MessengerFactory::server($unix, $this->loop); | ||
|
||
$script = sprintf($this->script, EPROCESS_AUTOLOAD, $unix, $class, base64_encode($this->serialize($data))); | ||
|
||
$this->process = new PhpProcess($script); | ||
$this->process->start(); | ||
|
||
return $messenger; | ||
} | ||
|
||
public function kill() | ||
{ | ||
$this->process->stop(); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
namespace EProcess\Adapter; | ||
|
||
use EProcess\Application\ApplicationFactory; | ||
use EProcess\MessengerFactory; | ||
use React\EventLoop\Factory; | ||
|
||
class Thread extends \Thread | ||
{ | ||
private $class; | ||
private $unix; | ||
private $data; | ||
|
||
public function __construct($unix, $class, array $data) | ||
{ | ||
$this->unix = $unix; | ||
$this->class = $class; | ||
$this->data = $data; | ||
} | ||
|
||
public function run() | ||
{ | ||
require_once EPROCESS_AUTOLOAD; | ||
|
||
$loop = Factory::create(); | ||
|
||
$messenger = MessengerFactory::client($this->unix, $loop); | ||
$application = ApplicationFactory::create($this->class); | ||
|
||
$application->messenger($messenger); | ||
$application->loop($loop); | ||
$application->data($this->data); | ||
|
||
$messenger->emit('initialized', true); | ||
|
||
try { | ||
$application->run(); | ||
$loop->run(); | ||
} catch (\Exception $e) { | ||
echo $e; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
namespace EProcess\Application; | ||
|
||
use EProcess\Behaviour\UniversalSerializer; | ||
use EProcess\Behaviour\Workable; | ||
use Evenement\EventEmitterTrait; | ||
use React\EventLoop\LoopInterface; | ||
use EProcess\Messenger; | ||
use EProcess\Message; | ||
|
||
abstract class Application | ||
{ | ||
use EventEmitterTrait { | ||
EventEmitterTrait::emit as emitterEmit; | ||
} | ||
use UniversalSerializer; | ||
use Workable; | ||
|
||
private $loop; | ||
private $messenger; | ||
private $data; | ||
|
||
public function loop(LoopInterface $loop = null) | ||
{ | ||
if ($loop) { | ||
$this->loop = $loop; | ||
} | ||
|
||
return $this->loop; | ||
} | ||
|
||
public function messenger(Messenger $messenger = null) | ||
{ | ||
if ($messenger) { | ||
$messenger->on('message', function(Message $message) { | ||
$this->emitterEmit($message->getEvent(), [$message->getContent()]); | ||
}); | ||
|
||
$this->messenger = $messenger; | ||
} | ||
|
||
return $this->messenger; | ||
} | ||
|
||
public function data(array $data = null) | ||
{ | ||
if ($data) { | ||
$this->data = $data; | ||
} | ||
|
||
return $this->data; | ||
} | ||
|
||
public function emit($event, $data) | ||
{ | ||
$this->messenger->emit($event, $data); | ||
} | ||
|
||
abstract public function run(); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace EProcess\Application; | ||
|
||
use React\EventLoop\Factory; | ||
|
||
class ApplicationFactory | ||
{ | ||
public static function launch($fqcn) | ||
{ | ||
$application = static::create($fqcn); | ||
|
||
try { | ||
$application->run(); | ||
$application->loop()->run(); | ||
} catch (\Exception $e) { | ||
echo $e; | ||
} | ||
} | ||
|
||
public static function create($fqcn) | ||
{ | ||
if (!is_subclass_of($fqcn, Application::class)) { | ||
throw new \InvalidArgumentException('Should be a subclass of Application'); | ||
} | ||
|
||
$loop = Factory::create(); | ||
|
||
$application = new $fqcn(); | ||
$application->loop($loop); | ||
|
||
return $application; | ||
} | ||
} |
Oops, something went wrong.