123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- <?php
- namespace WorkflowBundle\Command;
- use Symfony\Component\Console\Command\Command;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Input\InputOption;
- use Symfony\Component\Console\Output\OutputInterface;
- class LockWaitCommand extends Command
- {
- 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(
- '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');
- $dir = $input->getOption('dir');
- $timeout = $input->getOption('timeout');
- $no_exclusive = $input->getOption('no-exclusive');
- if ($filename) {
- $handle = $this->fopen($filename, $dir);
- if ($this->flock($handle, $timeout, $no_exclusive)) {
- $output->writeln('<info>OK</info>');
- }
- } else {
- $output->writeln('<error>Enter a valid filename</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 int $timeout
- * @param boolean $no_exclusive
- *
- * @throws \Exception
- */
- protected function flock($handle, $timeout = 600, $no_exclusive = false)
- {
- pcntl_signal(SIGALRM, function() {
- exit(1);
- });
- pcntl_alarm($timeout);
- try {
- $operation = LOCK_EX;
- if ($no_exclusive) {
- $operation = LOCK_SH;
- }
- if (!flock($handle, $operation)) {
- throw new \Exception("Timeout");
- }
- } finally {
- pcntl_alarm(0);
- pcntl_signal_dispatch();
- pcntl_signal(SIGALRM, SIG_DFL);
- }
- flock($handle, LOCK_UN);
- fclose($handle);
-
- return true;
- }
- }
|