From 6df281b984e5b2036495d07dcd820a2c545e8203 Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Thu, 3 Oct 2024 16:21:20 +0200 Subject: [PATCH] feat: add example runner for parallel execution of examples --- Makefile | 6 +---- composer.json | 2 ++ example | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100755 example diff --git a/Makefile b/Makefile index 5e81c15b..388a4bd5 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,4 @@ coverage: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=coverage run-all-examples: - for file in ./examples/*.php; do \ - echo "Running $$file..."; \ - php $$file; \ - echo ""; \ - done + ./example diff --git a/composer.json b/composer.json index b5303284..cb95d2f4 100644 --- a/composer.json +++ b/composer.json @@ -35,6 +35,8 @@ "symfony/css-selector": "^6.4 || ^7.1", "symfony/dom-crawler": "^6.4 || ^7.1", "symfony/dotenv": "^6.4 || ^7.1", + "symfony/finder": "^6.4 || ^7.1", + "symfony/process": "^6.4 || ^7.1", "symfony/var-dumper": "^6.4 || ^7.1" }, "conflict": { diff --git a/example b/example new file mode 100755 index 00000000..89d9b2c3 --- /dev/null +++ b/example @@ -0,0 +1,67 @@ +#!/usr/bin/env php +setDescription('Runs all LLM Chain examples in folder examples/') + ->setCode(function (InputInterface $input, OutputInterface $output) { + $io = new SymfonyStyle($input, $output); + $io->title('LLM Chain Examples'); + + $examples = (new Finder()) + ->in(__DIR__.'/examples') + ->name('*.php') + ->sortByName() + ->files(); + + /** @var array{example: SplFileInfo, section: ConsoleSectionOutput, process: Process, state: 'running'|'finished'} $exampleRuns */ + $exampleRuns = []; + foreach ($examples as $example) { + $exampleRuns[] = [ + 'example' => $example, + 'section' => $section = $output->section(), + 'process' => $process = new Process(['php', $example->getRealPath()]), + 'state' => 'running', + ]; + + $process->start(); + $section->writeln(sprintf('Example %s: Running', $example->getFilename())); + } + + $examplesRunning = fn () => array_reduce($exampleRuns, fn ($running, $example) => $running || $example['process']->isRunning(), false); + $examplesSuccessful = fn () => array_reduce($exampleRuns, fn ($successful, $example) => $successful && $example['process']->isSuccessful(), true); + + while ($examplesRunning()) { + sleep(1); + foreach ($exampleRuns as $run) { + if ('running' === $run['state'] && !$run['process']->isRunning()) { + $result = $run['process']->isSuccessful() ? 'Finished' : 'Failed'; + $run['section']->overwrite(sprintf('Example %s: %s', $run['example']->getFilename(), $result)); + $run['state'] = 'finished'; + } + } + } + + $io->newLine(); + if (!$examplesSuccessful()) { + $io->error('Some examples failed!'); + + return Command::FAILURE; + } + + $io->success('All examples ran successfully!'); + + return Command::SUCCESS; + }) + ->run();