Reputation: 353
I am using Symfony2 and I want to run a long script written in C++ (for example 60 minutes).
Now I do it via shell_exec()
:
$pid = shell_exec('nohup my/program/written/in/c++.out some arguments > /dev/null 2>/dev/null & echo $!');
If I keep refreshing a page the script runs fine, but if I go AFK the script is terminated with process of PHP server (/usr/bin/php-cgi).
Is there a way to isolate C++ program from PHP server process? With nohup the process has ppid = 1, so it should be isolated, but it is not.
Upvotes: 1
Views: 3333
Reputation: 2970
You can look at the Symfony Process Component : http://symfony.com/doc/current/components/process.html
$process = new Process('nohup my/program/written/in/c++.out some arguments');
$process->run();
You will be able to run your process.
Upvotes: 2
Reputation: 2462
You can create symfony2 console command "myapp:my-command-name" that will run your c++ command
class MyStandaloneCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('myapp:my-command-name')
->setDescription('Will run standalone c++')
->addArgument('arg1', InputArgument::REQUIRED, 'Some arg');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$arg1 = $input->getArgument('arg1');
$result = shell_exec('nohup my/program/written/in/c++.out '.$arg1.' 2>&1');
$output->writeln('My cool command is started');
return true;
}
}
Then use JMSJobBundle
http://jmsyst.com/bundles/JMSJobQueueBundle/master/installation
Where you can create a queue of you console commands something like:
class HomeController ... {
// inject service here
private $cronJobHelper;
// inject EM here
private $em;
public function indexAction(){
$job = $this->cronJobHelper->createConsoleJob('myapp:my-command-name', $event->getId(), 10);
$this->em->persist($job);
$this->em->persist($job);
$this->em->flush();
}
use JMS\JobQueueBundle\Entity\Job;
class CronJobHelper{
public function createConsoleJob($consoleFunction, $params, $delayToRunInSeconds, $priority = Job::PRIORITY_DEFAULT, $queue = Job::DEFAULT_QUEUE){
if(!is_array($params)){
$params = [$params];
}
$job = new Job($consoleFunction, $params, 1, $queue, $priority);
$date = $job->getExecuteAfter();
$date = new \DateTime('now');
$date->setTimezone(new \DateTimeZone('UTC')); //just in case
$date->add(new \DateInterval('PT'.$delayToRunInSeconds.'S'));
$job->setExecuteAfter($date);
return $job;
}
}
Upvotes: 0