Ver código fonte

Merge branch 'master' of ssh://200.50.168.30:222/VendorSoftwareFlowdat3/WorkflowBundle

Maximiliano Schvindt 8 anos atrás
pai
commit
a56212fee9
2 arquivos alterados com 124 adições e 1 exclusões
  1. 122 0
      Command/LockWaitCommand.php
  2. 2 1
      Services/TaskLoggerService.php

+ 122 - 0
Command/LockWaitCommand.php

@@ -0,0 +1,122 @@
+<?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);
+    }
+
+}

+ 2 - 1
Services/TaskLoggerService.php

@@ -61,7 +61,7 @@ class TaskLoggerService implements ConsumerInterface
     /**
      * @param string $filename
      * 
-     * @return string
+     * @return array
      */
     public function runProcess($filename)
     {
@@ -71,6 +71,7 @@ class TaskLoggerService implements ConsumerInterface
         return array(
             'output' => $process->getOutput(),
             'error' => $process->getErrorOutput(),
+            'exit_code' => $process->getExitCode(),
         );
     }