123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- <?php
- namespace WorkflowBundle\Command;
- use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Input\InputOption;
- use Symfony\Component\Console\Output\OutputInterface;
- use WorkflowBundle\Services\TaskLoggerService;
- class LockWaitCommand extends ContainerAwareCommand
- {
- protected function configure()
- {
- $this
- ->setName('lock:wait')
- ->setDescription('Lock wait command')
- ->setHelp('Lock wait command. Wait for lock a file. The lock can be either exclusive or shared')
- ->addArgument('filename', InputOption::VALUE_REQUIRED, 'Filename')
- ->addOption('command', 'c', InputOption::VALUE_REQUIRED, 'Command to execute')
- ->addOption('dir', null, InputOption::VALUE_REQUIRED, 'Directory path file', '/tmp')
- ->addOption('timeout', null, InputOption::VALUE_REQUIRED, 'Timeout execution (ms)', 600)
- ->addOption('no-exclusive', 'no-e', InputOption::VALUE_NONE, 'No exclusive lock')
- ;
- }
- /**
- * @param InputInterface $input
- * @param OutputInterface $output
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $filename = $input->getArgument('filename');
- $command = $input->getOption('command');
- $dir = $input->getOption('dir');
- $timeout = $input->getOption('timeout');
- $no_exclusive = $input->getOption('no-exclusive');
- if ($filename && $command) {
- $handle = $this->fopen($filename, $dir);
- $this->flock($handle, $command, $timeout, $no_exclusive);
- } else {
- $output->writeln('<error>Enter a valid filename and command</error>');
- }
- }
- /**
- * @param string $filename
- * @param string $dir
- *
- * @return resource
- */
- protected function fopen($filename, $dir)
- {
- // limpio el filename completo
- $invalid_chars = array(" ", '"', "'", "&", "\\", "?", "#", "$", "//");
- $delimiter = DIRECTORY_SEPARATOR;
- $dir_pieces = explode($delimiter, str_replace($invalid_chars, '', $dir));
- $filename_pieces = explode($delimiter, str_replace($invalid_chars, '', $filename));
- $last_filename_piece = array_pop($filename_pieces);
-
- $dir = $delimiter . implode($delimiter, array_filter(array_merge($dir_pieces, $filename_pieces)));
- $filename = $dir . $delimiter . $last_filename_piece;
-
- if (!file_exists($dir)) {
- mkdir($dir, 0777, true);
- }
- return fopen($filename, "w+");
- }
-
- /**
- * @param resource $handle
- * @param string $command
- * @param int $timeout
- * @param boolean $no_exclusive
- *
- * @return boolean
- */
- protected function flock($handle, $command, $timeout = 600, $no_exclusive = false)
- {
- pcntl_signal(SIGALRM, function() {
- exit(1);
- });
- pcntl_alarm($timeout);
- $operation = LOCK_EX;
- if ($no_exclusive) {
- $operation = LOCK_SH;
- }
- if (flock($handle, $operation)) {
- $exit_code = $this->runProcess($command)['exit_code'];
- } else {
- echo 'No se pudo obtener el lock' . PHP_EOL;
- $exit_code = 1;
- }
-
- pcntl_alarm(0);
- pcntl_signal_dispatch();
- pcntl_signal(SIGALRM, SIG_DFL);
-
- flock($handle, LOCK_UN);
- fclose($handle);
-
- exit($exit_code);
- }
-
-
- /**
- * @param string $filename
- *
- * @return array
- */
- protected function runProcess($filename)
- {
- /* @var $taskloggerService TaskLoggerService */
- $taskloggerService = $this->getContainer()->get('flowdat_tasklogger_service');
-
- return $taskloggerService->runProcess($filename);
- }
- }
|