kriswallsmith / spork

Experimental library for forking PHP
MIT License
587 stars 52 forks source link

Add example to the docs for queueing several processes #3

Closed frastel closed 12 years ago

frastel commented 12 years ago

Currently it is unclear to me how queueing of several processes/callbacks should be implemented the correct way. I used the attached example (a simple symfony2 command) where some file should be added to one archive. This workflow does not work as the file additions are overwriting themselves and at the end not every file will be placed in the archive. So this feels wrong and i think it should be handled in a fork->then->fork->then workflow, but i do not get it running in a nice way.

Could you maybe add an example how this stuff should be handled? And please ignore the used example here, i think it is quite useless but i could not think of another simple example :)

class SporkDebugCommand extends ContainerAwareCommand
{

    protected function configure()
    {
        $this
            ->setName('spork:debug')
            ->addOption('loops', null, InputOption::VALUE_REQUIRED, 'Loops', 10);
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $zipPath = $this->getContainer()->getParameter('kernel.cache_dir') . '/archive_' . uniqid() . '.zip';
        $output->writeln('archive: '.$zipPath);
        $output->writeln('process: '.posix_getpid());

        $zip = new \ZipArchive();
        if ($zip->open($zipPath, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE) !== true) {
            throw new \Exception('could not open archive');
        }

        $manager = new ProcessManager(new DeferredFactory());
        $file = __FILE__;

        // adding something to a zip archive but in different processes
        for ($i = 0; $i <= $input->getOption('loops'); $i++) {
            $manager->fork(function() use ($zip, $file, $i, $output) {
                echo "$i";

                $output->writeln(sprintf('loop process [%s]: [%s]', $i, posix_getpid()));
                $zip->addFile($file, $i.'_'.basename($file));
            })->then(function($forkOutput, $forkStatus) use ($output) {
                // do something in the parent process when it's done!
                $output->writeln('then process: ' .  posix_getpid(). " output: $forkOutput status: $forkStatus");
            });

        }

        $zip->close();
    }
}
kriswallsmith commented 12 years ago

I don't think multiple processes can add files to a single zip archive at the same time. This probably needs to be done serially. I've added an example of uploading files to a CDN to the README.