-
-
Save kgilden/5d3c9239caccf4000621 to your computer and use it in GitHub Desktop.
AsseticBundle & Spork fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* This file is part of Spork, an OpenSky project. | |
* | |
* (c) OpenSky Project Inc | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
namespace Spork\Batch; | |
use Spork\Batch\Strategy\ChunkStrategy; | |
use Spork\Batch\Strategy\StrategyInterface; | |
use Spork\Exception\UnexpectedTypeException; | |
use Spork\ProcessManager; | |
class BatchJob | |
{ | |
private $manager; | |
private $data; | |
private $strategy; | |
private $name; | |
private $callback; | |
public function __construct(ProcessManager $manager, $data = null, StrategyInterface $strategy = null) | |
{ | |
$this->manager = $manager; | |
$this->data = $data; | |
$this->strategy = $strategy ?: new ChunkStrategy(); | |
$this->name = '<anonymous>'; | |
} | |
public function setName($name) | |
{ | |
$this->name = $name; | |
return $this; | |
} | |
public function setStrategy(StrategyInterface $strategy) | |
{ | |
$this->strategy = $strategy; | |
return $this; | |
} | |
public function setData($data) | |
{ | |
$this->data = $data; | |
return $this; | |
} | |
public function setCallback($callback) | |
{ | |
if (!is_callable($callback)) { | |
throw new UnexpectedTypeException($callback, 'callable'); | |
} | |
$this->callback = $callback; | |
return $this; | |
} | |
public function execute($callback = null) | |
{ | |
if (null !== $callback) { | |
$this->setCallback($callback); | |
} | |
return $this->manager->fork($this)->setName($this->name.' batch'); | |
} | |
/** | |
* Runs in a child process. | |
* | |
* @see execute() | |
*/ | |
public function __invoke() | |
{ | |
$forks = array(); | |
foreach ($this->strategy->createBatches($this->data) as $index => $batch) { | |
$forks[] = $this->manager | |
->fork($this->strategy->createRunner($batch, $this->callback)) | |
->setName(sprintf('%s batch #%d', $this->name, $index)) | |
; | |
} | |
// block until all forks have exited | |
$this->manager->wait(); | |
$results = array(); | |
foreach ($forks as $fork) { | |
// This is the new part - getting error from the fork and throwing an exception. | |
// Perhaps we could also use the messaging system? | |
if ($error = $fork->getError()) { | |
throw new \RuntimeException(sprintf('%s (%d) thrown in fork (%d): "%s" (%s:%d)', | |
$error->getClass(), | |
$error->getCode(), | |
$fork->getPid(), | |
$error->getMessage(), | |
$error->getFile(), | |
$error->getLine() | |
)); | |
} | |
$results = array_merge($results, $fork->getResult()); | |
} | |
return $results; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* This file is part of the Symfony framework. | |
* | |
* (c) Fabien Potencier <fabien@symfony.com> | |
* | |
* This source file is subject to the MIT license that is bundled | |
* with this source code in the file LICENSE. | |
*/ | |
namespace Symfony\Bundle\AsseticBundle\Command; | |
use Spork\Batch\Strategy\ChunkStrategy; | |
use Spork\EventDispatcher\WrappedEventDispatcher; | |
use Spork\ProcessManager; | |
use Symfony\Component\Console\Input\ArrayInput; | |
use Symfony\Component\Console\Input\InputArgument; | |
use Symfony\Component\Console\Input\InputInterface; | |
use Symfony\Component\Console\Input\InputOption; | |
use Symfony\Component\Console\Output\ConsoleOutputInterface; | |
use Symfony\Component\Console\Output\OutputInterface; | |
/** | |
* Dumps assets to the filesystem. | |
* | |
* @author Kris Wallsmith <kris@symfony.com> | |
*/ | |
class DumpCommand extends AbstractCommand | |
{ | |
private $spork; | |
protected function configure() | |
{ | |
$this | |
->setName('assetic:dump') | |
->setDescription('Dumps all assets to the filesystem') | |
->addArgument('write_to', InputArgument::OPTIONAL, 'Override the configured asset root') | |
->addOption('forks', null, InputOption::VALUE_REQUIRED, 'Fork work across many processes (requires kriswallsmith/spork)') | |
->addOption('watch', null, InputOption::VALUE_NONE, 'DEPRECATED: use assetic:watch instead') | |
->addOption('force', null, InputOption::VALUE_NONE, 'DEPRECATED: use assetic:watch instead') | |
->addOption('period', null, InputOption::VALUE_REQUIRED, 'DEPRECATED: use assetic:watch instead', 1) | |
; | |
} | |
protected function initialize(InputInterface $input, OutputInterface $stdout) | |
{ | |
if (null !== $input->getOption('forks')) { | |
if (!class_exists('Spork\ProcessManager')) { | |
throw new \RuntimeException('The --forks option requires that package kriswallsmith/spork be installed'); | |
} | |
if (!is_numeric($input->getOption('forks'))) { | |
throw new \InvalidArgumentException('The --forks options must be numeric'); | |
} | |
$this->spork = new ProcessManager( | |
new WrappedEventDispatcher($this->getContainer()->get('event_dispatcher')), | |
null, | |
$this->getContainer()->getParameter('kernel.debug') | |
); | |
} | |
parent::initialize($input, $stdout); | |
} | |
protected function execute(InputInterface $input, OutputInterface $stdout) | |
{ | |
// capture error output | |
$stderr = $stdout instanceof ConsoleOutputInterface | |
? $stdout->getErrorOutput() | |
: $stdout; | |
if ($input->getOption('watch')) { | |
$stderr->writeln( | |
'<error>The --watch option is deprecated. Please use the '. | |
'assetic:watch command instead.</error>' | |
); | |
// build assetic:watch arguments | |
$arguments = array( | |
'command' => 'assetic:watch', | |
'write_to' => $this->basePath, | |
'--period' => $input->getOption('period'), | |
'--env' => $input->getOption('env'), | |
); | |
if ($input->getOption('no-debug')) { | |
$arguments['--no-debug'] = true; | |
} | |
if ($input->getOption('force')) { | |
$arguments['--force'] = true; | |
} | |
$command = $this->getApplication()->find('assetic:watch'); | |
return $command->run(new ArrayInput($arguments), $stdout); | |
} | |
// print the header | |
$stdout->writeln(sprintf('Dumping all <comment>%s</comment> assets.', $input->getOption('env'))); | |
$stdout->writeln(sprintf('Debug mode is <comment>%s</comment>.', $this->am->isDebug() ? 'on' : 'off')); | |
$stdout->writeln(''); | |
if ($this->spork) { | |
$batch = $this->spork->createBatchJob( | |
$this->am->getNames(), | |
new ChunkStrategy($input->getOption('forks')) | |
); | |
$self = $this; | |
$batch->execute(function ($name) use ($self, $stdout) { | |
$self->dumpAsset($name, $stdout); | |
})->fail(function ($fork) { | |
// Here we're getting the error and outputting it as an exception to 100% | |
// be sure that the dump command fails with a non-zero exit status | |
$error = $fork->getError(); | |
throw new \RuntimeException(sprintf('%s (%d) thrown in fork (%d): "%s" (%s:%d)', | |
$error->getClass(), | |
$error->getCode(), | |
$fork->getPid(), | |
$error->getMessage(), | |
$error->getFile(), | |
$error->getLine() | |
)); | |
}); | |
} else { | |
foreach ($this->am->getNames() as $name) { | |
$this->dumpAsset($name, $stdout); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment