public function runTestProcess($arguments, $expectedExitCode = 0, $timeout = 5) { $command = __DIR__ . '/../../../../bin/phpunit-parallel ' . $arguments; $loop = Factory::create(); $p = new Process($command); $p->start($loop); $stdout = ''; $stderr = ''; $timer = $loop->addTimer($timeout, function () use($arguments, $p, $stdout, $stderr) { $p->terminate(SIGKILL); $this->fail("running phpunit-parallel with '{$arguments}' did not complete in time\nstdout: {$stdout}\nstderr: {$stderr}\n"); }); $p->stdout->on('data', function ($data) use(&$stdout) { $stdout .= $data; }); $p->stderr->on('data', function ($data) use(&$stderr) { $stderr .= $data; }); $p->on('exit', function () use($timer) { $timer->cancel(); }); $loop->run(); if ($p->getExitCode() !== $expectedExitCode) { $this->fail("Process exited with code {$p->getExitCode()}, expected {$expectedExitCode}\nstdout: {$stdout}\nstderr: {$stderr}\n"); } return [$stdout, $stderr]; }
/** @internal */ public function go(Process $process) { $this->deferred = $deferred = new Deferred(); $this->process = $process; $buffered = null; $process->stdout->on('data', function ($data) use(&$buffered) { if ($data !== '') { $buffered .= $data; } }); $process->on('exit', function ($code) use($deferred) { if ($code !== 0) { $deferred->reject($code); } else { $deferred->resolve(); } }); $that = $this; $this->promise = $deferred->promise()->then(function () use(&$buffered, $that) { if ($buffered === null) { $buffered = true; } else { $buffered = $that->parseValue(trim($buffered)); } return $buffered; }); }
/** * Runs the application * * @return void */ public function run() { if (!self::$defaultApplication) { self::$defaultApplication = $this; } $application = $this; if (OsDetector::isMacOS()) { $processName = './phpgui-i386-darwin'; $processPath = __DIR__ . '/../lazarus/phpgui-i386-darwin.app/Contents/MacOS/'; } elseif (OsDetector::isFreeBSD()) { $processName = './phpgui-x86_64-freebsd'; $processPath = __DIR__ . '/../lazarus/'; } elseif (OsDetector::isUnix()) { $processName = './phpgui-x86_64-linux'; $processPath = __DIR__ . '/../lazarus/'; } elseif (OsDetector::isWindows()) { $processName = '.\\phpgui-x86_64-win64'; $processPath = __DIR__ . '\\..\\lazarus\\'; } else { throw new RuntimeException('Operational System not identified by PHP-GUI.'); } $this->process = $process = new Process($processName, $processPath); $this->process->on('exit', function () use($application) { $application->loop->stop(); }); $this->receiver = $receiver = new Receiver($this); $this->sender = $sender = new Sender($this, $receiver); $this->loop->addTimer(0.001, function ($timer) use($process, $application, $receiver) { $process->start($timer->getLoop()); // We need to pause all default streams // The react/loop uses fread to read data from streams // On Windows, fread always is blocking // Stdin is paused, we use our own way to write on it $process->stdin->pause(); // Stdout is paused, we use our own way to read it $process->stdout->pause(); // Stderr is paused for avoiding fread $process->stderr->pause(); $process->stdout->on('data', function ($data) use($receiver) { $receiver->onData($data); }); $process->stderr->on('data', function ($data) { if (!empty($data)) { Output::err($data); } }); $application->running = true; // Bootstrap the application $application->fire('start'); }); $this->loop->addPeriodicTimer(0.001, function () use($application) { $application->sender->tick(); if (@is_resource($application->process->stdout->stream)) { $application->receiver->tick(); } }); $this->loop->run(); }
public function __construct(LoopInterface $loop, SpawnerInterface $spawner, $id, $cmd, $args, $onData, $onExit) { $this->id = $id; $this->loop = $loop; $this->process = new Process($spawner->spawn($cmd, $args)); $this->process->on('exit', function ($exitCode, $termSignal) use($onExit) { call_user_func($onExit, $exitCode, $termSignal); }); $this->process->start($loop); $this->out = $this->process->stdout; $this->in = $this->process->stdin; $this->err = $this->process->stderr; $this->out->on('data', function ($data) use($onData) { call_user_func($onData, $data); }); $this->err->on('data', function ($data) use($onData) { call_user_func($onData, $data); }); }
/** * Promise that resolves once child process exits * * @param LoopInterface $loop ReactPHP event loop. * @param Process $process Child Process to run. * * @return \React\Promise\PromiseInterface */ function childProcessPromise(LoopInterface $loop, Process $process) { $deferred = new Deferred(); $buffers = ['stderr' => '', 'stdout' => '']; $process->on('exit', function ($exitCode) use($deferred, &$buffers) { $deferred->resolve(new ProcessOutcome($exitCode, $buffers['stderr'], $buffers['stdout'])); }); \WyriHaximus\React\futurePromise($loop, $process)->then(function (Process $process) use($loop, &$buffers) { $process->start($loop); $process->stderr->on('data', function ($output) use(&$buffers) { $buffers['stderr'] .= $output; }); $process->stdout->on('data', function ($output) use(&$buffers) { $buffers['stdout'] .= $output; }); }); return $deferred->promise(); }
/** * @return PromiseInterface */ public function execute($program = '') { if ($program === '') { return new RejectedPromise(); } $deferred = new Deferred(); $process = new Process('exec hash ' . $program); $process->on('exit', function ($exitCode) use($deferred) { if ($exitCode == 0) { $deferred->resolve(); return; } $deferred->reject(); }); \WyriHaximus\React\futurePromise($this->loop, $process)->then(function (Process $process) { $process->start($this->loop); }); return $deferred->promise(); }
/** * @return PromiseInterface */ public function execute() { $deferred = new Deferred(); $buffer = ''; $process = new Process('exec nproc'); $process->on('exit', function ($exitCode) use($deferred, &$buffer) { if ($exitCode == 0) { $deferred->resolve($buffer); return; } $deferred->reject(); }); \WyriHaximus\React\futurePromise($this->loop, $process)->then(function (Process $process) use(&$buffer) { $process->start($this->loop); $process->stdout->on('data', function ($output) use(&$buffer) { $buffer += $output; }); }); return $deferred->promise(); }
/** * @param InputInterface $input * @param OutputInterface $output * * @return void */ protected function executeMultiThreadStreamManager(InputInterface $input, OutputInterface $output) { /** @var Generator $streams */ $streams = $this->getContainer()->get('sim.event_store.replay')->streams(); $loop = Factory::create(); $threads = 0; $iteration = 0; $loop->addPeriodicTimer(0.001, function ($timer) use($loop, $streams, &$threads, &$iteration, $input, $output) { if ($threads >= $input->getOption('threads')) { return; } if (!$streams->valid()) { $loop->stop(); } $threads++; $stream = $streams->current(); $output->writeln(sprintf('<info>Dispatching thread for event stream %s</info>', $stream)); $process = new Process(sprintf('app/console simgroep:eventsourcing:events:replay %s --stream %s', $input->getArgument('projector'), $stream)); $process->on('exit', function ($exitCode, $termSignal) use(&$threads, $output) { $threads--; if ($exitCode !== 0) { $output->writeln(sprintf('<error>Process ended with code %s</error>', $exitCode)); } }); $process->start($timer->getLoop()); if ($input->getOption('verbose')) { $process->stdout->on('data', function ($message) use($output) { $output->write($message); }); } $output->writeln(sprintf('<info>Stream %s | %s streams/sec</info>', str_pad(++$iteration, 10, ' ', STR_PAD_LEFT), str_pad($this->perSecond($iteration), 6, ' ', STR_PAD_LEFT))); $streams->next(); }); $loop->run(); }
public function testTerminateWithStopAndContinueSignalsUsingEventLoop() { if (defined('PHP_WINDOWS_VERSION_BUILD')) { $this->markTestSkipped('Windows does not report signals via proc_get_status()'); } if (!defined('SIGSTOP') && !defined('SIGCONT')) { $this->markTestSkipped('SIGSTOP and/or SIGCONT is not defined'); } $loop = $this->createloop(); $process = new Process('sleep 1; exit 0'); $called = false; $exitCode = 'initial'; $termSignal = 'initial'; $process->on('exit', function () use(&$called, &$exitCode, &$termSignal) { $called = true; $exitCode = func_get_arg(0); $termSignal = func_get_arg(1); }); $loop->addTimer(0.001, function (Timer $timer) use($process) { $process->start($timer->getLoop()); $process->terminate(SIGSTOP); $this->assertSoon(function () use($process) { $this->assertTrue($process->isStopped()); $this->assertTrue($process->isRunning()); $this->assertEquals(SIGSTOP, $process->getStopSignal()); }); $process->terminate(SIGCONT); $this->assertSoon(function () use($process) { $this->assertFalse($process->isStopped()); $this->assertEquals(SIGSTOP, $process->getStopSignal()); }); }); $loop->run(); $this->assertTrue($called); $this->assertSame(0, $exitCode); $this->assertNull($termSignal); $this->assertFalse($process->isRunning()); $this->assertSame(0, $process->getExitCode()); $this->assertNull($process->getTermSignal()); $this->assertFalse($process->isTerminated()); }
protected function generateProcessOrSkipGeneration(LmStateDto $receivedControlDto) { $processesNumber = count($this->processes); if ($processesNumber < $this->tasks && ($this->processManagerDto->getMaxSimultaneousProcesses() > 1 ? $processesNumber < $this->processManagerDto->getMaxSimultaneousProcesses() : true)) { $this->logger->info("PM come to create new process."); $this->logger->info("Tasks number:" . serialize($this->tasks)); $this->logger->info("Processes number:" . serialize(count($this->processes))); $workerProcess = new Process($this->processManagerDto->getWorkerProcessCommand()); $workerProcess->start($this->loop); $workerProcessPid = $workerProcess->getPid(); //to protect from bug of proc_get_status if (!is_null($workerProcessPid)) { if ($this->processManagerDto->getPerformerSocketsParams()) { $workerProcess->stdin->write(json_encode($this->getPreparedSocketParams())); } $workerProcess->stdout->on(EventsConstants::DATA, function ($data) use(&$workerProcessPid) { //$data = @json_decode($data); //$this->logger->warning("Worker STDOUT: " . serialize($data)); }); $workerProcess->on(EventsConstants::PROCESS_EXIT, function ($exitCode, $termSignal) { $this->logger->warning("Worker sub-process exit with code: " . serialize($exitCode) . " | and term signal: " . serialize($termSignal)); }); $processDto = $this->getProcessDto($workerProcessPid); $this->processes[$workerProcessPid] = $workerProcess; $this->dtoContainer->setDto($processDto); } else { $this->dtoContainer->setDto(new PmStateDto()); } } else { //all processes already created, but not finished yet if (!$this->allTasksCreated) { $this->allTasksCreated = true; } $pmStateDto = new PmStateDto(); $pmStateDto->setAllProcessesCreated(true); $this->dtoContainer->setDto($pmStateDto); $this->logger->info("PM send all processes created."); $this->logger->info("Tasks number:" . serialize($this->tasks)); $this->logger->info("Processes number:" . count($this->processes)); } return null; }
protected function queueProcess() { if (!$this->benchmarks->valid()) { return; } $b = $this->benchmarks->current(); $this->benchmarks->next(); $key = serialize([$b->benchmark, $b->subbenchmark, $b->count]); if (!isset($this->stdout[$key])) { $this->stdout[$key] = ''; } if (!isset($this->runtimes[$key])) { $this->runtimes[$key] = []; } $current_process_id = $this->process_id; $this->process_id++; $this->processes[$current_process_id] = $process = new Process($b->command); $start = null; $process->on('exit', function ($code, $signal) use($b, $key, &$current_process_id, &$start) { $this->runtimes[$key][] = microtime(true) - $start; $this->output->writeln('<comment>End ' . $b->benchmark . '-' . $b->subbenchmark . ' ' . $b->count . ' #' . $b->execution . '</comment>'); unset($this->processes[$current_process_id]); $this->queueProcess(); }); $this->loop->addTimer(0.001, function ($timer) use($process, $key, $b, &$start) { $this->output->writeln('<comment>Start ' . $b->benchmark . '-' . $b->subbenchmark . ' ' . $b->count . ' #' . $b->execution . '</comment>'); $start = microtime(true); $process->start($timer->getLoop()); $process->stdout->on('data', function ($data) use(&$stdout, $key) { $this->stdout[$key] .= $data; }); }); }
/** * @return null */ protected function initReplyStackProcess() { $this->replyStackProcess = new Process($this->publisherPulsarDto->getReplyStackCommandName()); $this->replyStackProcess->on(EventsConstants::PROCESS_EXIT, function ($exitCode, $termSignal) { $this->logger->warning("Reply stack sub-process exit with code: " . serialize($exitCode) . " | and term signal: " . serialize($termSignal)); }); $this->replyStackProcess->start($this->loop); $this->logger->debug("Init reply stack process."); /** * $data is serialized ReplyStackErrorDto */ $this->replyStackProcess->stdout->on(EventsConstants::DATA, function ($data) { $this->logger->debug($data); //throw new PublisherPulsarException("Error in STDOUT due to initReplyStackProcess. " . $data); }); $this->replyStackProcess->stderr->on(EventsConstants::DATA, function ($data) { $this->logger->critical($data); throw new PublisherPulsarException("Error in STDERR due to initReplyStackProcess. " . $data); }); $replyStackDto = new ReplyStackDto(); $replyStackDto->setReplyStackVsPulsarSocketAddress($this->pulsarSocketsParams->getReplyToReplyStackSocketAddress()); $replyStackDto->setReplyStackVsPerformersSocketAddress($this->pulsarSocketsParams->getReplyStackSocketAddress()); $replyStackDto->setLogger($this->publisherPulsarDto->getLogger()); $replyStackDto->setModuleName($this->publisherPulsarDto->getModuleName()); $this->replyStackProcess->stdin->write(serialize($replyStackDto)); $this->startAwaitBeReadyToAct = microtime(true); return null; }