From 2572fd7b325ae0bc5aed019cb85e31f05abd742e Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 20 Jun 2026 10:57:27 +0200 Subject: [PATCH 1/2] inline parlalel run here, to ease changes --- composer.json | 6 +- .../EasyCodingStandardApplication.php | 4 +- src/Console/Command/WorkerCommand.php | 4 +- .../Application/ParallelFileProcessor.php | 16 +- .../CommandLine/WorkerCommandLineFactory.php | 89 ++++++++++ .../Contract/SerializableInterface.php | 15 ++ src/Parallel/CpuCoreCountProvider.php | 25 +++ src/Parallel/Enum/Action.php | 23 +++ src/Parallel/Enum/Content.php | 18 ++ src/Parallel/Enum/ReactCommand.php | 18 ++ src/Parallel/Enum/ReactEvent.php | 28 ++++ .../ParallelShouldNotHappenException.php | 11 ++ src/Parallel/ScheduleFactory.php | 27 +++ src/Parallel/ValueObject/ParallelProcess.php | 154 ++++++++++++++++++ src/Parallel/ValueObject/ProcessPool.php | 67 ++++++++ src/Parallel/ValueObject/Schedule.php | 34 ++++ src/Parallel/WorkerRunner.php | 8 +- .../ValueObject/Error/CodingStandardError.php | 2 +- src/ValueObject/Error/FileDiff.php | 2 +- src/ValueObject/Error/SystemError.php | 2 +- 20 files changed, 533 insertions(+), 20 deletions(-) create mode 100644 src/Parallel/CommandLine/WorkerCommandLineFactory.php create mode 100644 src/Parallel/Contract/SerializableInterface.php create mode 100644 src/Parallel/CpuCoreCountProvider.php create mode 100644 src/Parallel/Enum/Action.php create mode 100644 src/Parallel/Enum/Content.php create mode 100644 src/Parallel/Enum/ReactCommand.php create mode 100644 src/Parallel/Enum/ReactEvent.php create mode 100644 src/Parallel/Exception/ParallelShouldNotHappenException.php create mode 100644 src/Parallel/ScheduleFactory.php create mode 100644 src/Parallel/ValueObject/ParallelProcess.php create mode 100644 src/Parallel/ValueObject/ProcessPool.php create mode 100644 src/Parallel/ValueObject/Schedule.php diff --git a/composer.json b/composer.json index b65e9a9ce82..5b411cce9a2 100644 --- a/composer.json +++ b/composer.json @@ -13,15 +13,19 @@ ], "require": { "php": ">=8.4", + "clue/ndjson-react": "^1.3", "composer/pcre": "^3.4", "composer/xdebug-handler": "^3.0.5", "entropy/entropy": "^0.4", + "fidry/cpu-core-counter": "^1.3", "friendsofphp/php-cs-fixer": "^3.95.5", "nette/utils": "^4.1", + "react/child-process": "^0.6.7", + "react/event-loop": "^1.6", + "react/socket": "^1.17", "sebastian/diff": "^9.0", "squizlabs/php_codesniffer": "^4.0.1", "symfony/finder": "^7.4", - "symplify/easy-parallel": "dev-main", "webmozart/assert": "^2.4" }, "require-dev": { diff --git a/src/Application/EasyCodingStandardApplication.php b/src/Application/EasyCodingStandardApplication.php index fe76185ac83..4e7cb021ec6 100644 --- a/src/Application/EasyCodingStandardApplication.php +++ b/src/Application/EasyCodingStandardApplication.php @@ -13,6 +13,8 @@ use Symplify\EasyCodingStandard\FileSystem\StaticRelativeFilePathHelper; use Symplify\EasyCodingStandard\Finder\SourceFinder; use Symplify\EasyCodingStandard\Parallel\Application\ParallelFileProcessor; +use Symplify\EasyCodingStandard\Parallel\CpuCoreCountProvider; +use Symplify\EasyCodingStandard\Parallel\ScheduleFactory; use Symplify\EasyCodingStandard\Parallel\ValueObject\Bridge; use Symplify\EasyCodingStandard\SniffRunner\ValueObject\Error\CodingStandardError; use Symplify\EasyCodingStandard\Utils\ParametersMerger; @@ -20,8 +22,6 @@ use Symplify\EasyCodingStandard\ValueObject\Error\FileDiff; use Symplify\EasyCodingStandard\ValueObject\Error\SystemError; use Symplify\EasyCodingStandard\ValueObject\Option; -use Symplify\EasyParallel\CpuCoreCountProvider; -use Symplify\EasyParallel\ScheduleFactory; final readonly class EasyCodingStandardApplication { diff --git a/src/Console/Command/WorkerCommand.php b/src/Console/Command/WorkerCommand.php index cf311538443..efda2c86f7c 100644 --- a/src/Console/Command/WorkerCommand.php +++ b/src/Console/Command/WorkerCommand.php @@ -15,9 +15,9 @@ use Symplify\EasyCodingStandard\Console\ExitCode; use Symplify\EasyCodingStandard\Console\Output\ConsoleOutputFormatter; use Symplify\EasyCodingStandard\MemoryLimitter; +use Symplify\EasyCodingStandard\Parallel\Enum\Action; +use Symplify\EasyCodingStandard\Parallel\Enum\ReactCommand; use Symplify\EasyCodingStandard\Parallel\WorkerRunner; -use Symplify\EasyParallel\Enum\Action; -use Symplify\EasyParallel\Enum\ReactCommand; /** * Inspired at: https://github.com/phpstan/phpstan-src/commit/9124c66dcc55a222e21b1717ba5f60771f7dda92 diff --git a/src/Parallel/Application/ParallelFileProcessor.php b/src/Parallel/Application/ParallelFileProcessor.php index 1b4660fc515..627fd104d3f 100644 --- a/src/Parallel/Application/ParallelFileProcessor.php +++ b/src/Parallel/Application/ParallelFileProcessor.php @@ -12,20 +12,20 @@ use React\Socket\TcpServer; use Symplify\EasyCodingStandard\Console\ExitCode; use Symplify\EasyCodingStandard\DependencyInjection\SimpleParameterProvider; +use Symplify\EasyCodingStandard\Parallel\CommandLine\WorkerCommandLineFactory; +use Symplify\EasyCodingStandard\Parallel\Enum\Action; +use Symplify\EasyCodingStandard\Parallel\Enum\Content; +use Symplify\EasyCodingStandard\Parallel\Enum\ReactCommand; +use Symplify\EasyCodingStandard\Parallel\Enum\ReactEvent; use Symplify\EasyCodingStandard\Parallel\ValueObject\Bridge; +use Symplify\EasyCodingStandard\Parallel\ValueObject\ParallelProcess; +use Symplify\EasyCodingStandard\Parallel\ValueObject\ProcessPool; +use Symplify\EasyCodingStandard\Parallel\ValueObject\Schedule; use Symplify\EasyCodingStandard\SniffRunner\ValueObject\Error\CodingStandardError; use Symplify\EasyCodingStandard\ValueObject\Configuration; use Symplify\EasyCodingStandard\ValueObject\Error\FileDiff; use Symplify\EasyCodingStandard\ValueObject\Error\SystemError; use Symplify\EasyCodingStandard\ValueObject\Option; -use Symplify\EasyParallel\CommandLine\WorkerCommandLineFactory; -use Symplify\EasyParallel\Enum\Action; -use Symplify\EasyParallel\Enum\Content; -use Symplify\EasyParallel\Enum\ReactCommand; -use Symplify\EasyParallel\Enum\ReactEvent; -use Symplify\EasyParallel\ValueObject\ParallelProcess; -use Symplify\EasyParallel\ValueObject\ProcessPool; -use Symplify\EasyParallel\ValueObject\Schedule; use Throwable; /** diff --git a/src/Parallel/CommandLine/WorkerCommandLineFactory.php b/src/Parallel/CommandLine/WorkerCommandLineFactory.php new file mode 100644 index 00000000000..879785f7838 --- /dev/null +++ b/src/Parallel/CommandLine/WorkerCommandLineFactory.php @@ -0,0 +1,89 @@ + $workerOptionValues option name => value, mirrored to the worker process + * @param string[] $paths + */ + public function create( + string $baseScript, + string $workerCommandName, + ?string $projectConfigFile, + array $workerOptionValues, + array $paths, + string $identifier, + int $port + ): string { + $processCommandArray = [escapeshellarg(PHP_BINARY), escapeshellarg($baseScript), $workerCommandName]; + + if ($projectConfigFile !== null) { + $processCommandArray[] = '--config'; + $processCommandArray[] = escapeshellarg($projectConfigFile); + } + + foreach ($this->mirrorCommandOptions($workerOptionValues) as $processCommandOption) { + $processCommandArray[] = $processCommandOption; + } + + // for TCP local server + $processCommandArray[] = '--port'; + $processCommandArray[] = (string) $port; + + $processCommandArray[] = '--identifier'; + $processCommandArray[] = escapeshellarg($identifier); + + foreach ($paths as $path) { + $processCommandArray[] = escapeshellarg($path); + } + + // set json output + $processCommandArray[] = '--output-format'; + $processCommandArray[] = escapeshellarg('json'); + + return implode(' ', $processCommandArray); + } + + /** + * @param array $workerOptionValues + * @return string[] + */ + private function mirrorCommandOptions(array $workerOptionValues): array + { + $processCommandOptions = []; + + foreach ($workerOptionValues as $optionName => $optionValue) { + // skip clutter + if ($optionValue === null) { + continue; + } + + if (is_bool($optionValue)) { + if ($optionValue) { + $processCommandOptions[] = self::OPTION_DASHES . $optionName; + } + + continue; + } + + if ($optionName === 'memory-limit') { + // does not accept -1 as value without assign + $processCommandOptions[] = '--' . $optionName . '=' . $optionValue; + } else { + $processCommandOptions[] = self::OPTION_DASHES . $optionName; + $processCommandOptions[] = escapeshellarg($optionValue); + } + } + + return $processCommandOptions; + } +} diff --git a/src/Parallel/Contract/SerializableInterface.php b/src/Parallel/Contract/SerializableInterface.php new file mode 100644 index 00000000000..ca296de6739 --- /dev/null +++ b/src/Parallel/Contract/SerializableInterface.php @@ -0,0 +1,15 @@ + $json + */ + public static function decode(array $json): self; +} diff --git a/src/Parallel/CpuCoreCountProvider.php b/src/Parallel/CpuCoreCountProvider.php new file mode 100644 index 00000000000..f2c23fc9f05 --- /dev/null +++ b/src/Parallel/CpuCoreCountProvider.php @@ -0,0 +1,25 @@ +getCount(); + } catch (NumberOfCpuCoreNotFound) { + return self::DEFAULT_CORE_COUNT; + } + } +} diff --git a/src/Parallel/Enum/Action.php b/src/Parallel/Enum/Action.php new file mode 100644 index 00000000000..7dfff2da86a --- /dev/null +++ b/src/Parallel/Enum/Action.php @@ -0,0 +1,23 @@ + $files + */ + public function create(int $cpuCores, int $jobSize, int $maxNumberOfProcesses, array $files): Schedule + { + $jobs = array_chunk($files, $jobSize); + $numberOfProcesses = min(count($jobs), $cpuCores); + + $numberOfProcesses = min($maxNumberOfProcesses, $numberOfProcesses); + + return new Schedule($numberOfProcesses, $jobs); + } +} diff --git a/src/Parallel/ValueObject/ParallelProcess.php b/src/Parallel/ValueObject/ParallelProcess.php new file mode 100644 index 00000000000..d3e10b09a7e --- /dev/null +++ b/src/Parallel/ValueObject/ParallelProcess.php @@ -0,0 +1,154 @@ +stdErr = $tmp; + $this->process = new Process($this->command, null, null, [ + 2 => $this->stdErr, + // todo is it fine to not have 0 and 1 FD? + ]); + $this->process->start($this->loop); + + $this->onData = $onData; + $this->onError = $onError; + + $this->process->on(ReactEvent::EXIT, function ($exitCode) use ($onExit): void { + if ($this->stdErr === null) { + throw new ParallelShouldNotHappenException(); + } + + $this->cancelTimer(); + + rewind($this->stdErr); + + /** @var string $streamContents */ + $streamContents = stream_get_contents($this->stdErr); + $onExit($exitCode, $streamContents); + + fclose($this->stdErr); + }); + } + + /** + * @param mixed[] $data + */ + public function request(array $data): void + { + $this->cancelTimer(); + $this->encoder->write($data); + $this->timer = $this->loop->addTimer($this->timetoutInSeconds, function (): void { + $onError = $this->onError; + + $errorMessage = sprintf('Child process timed out after %d seconds', $this->timetoutInSeconds); + $onError(new Exception($errorMessage)); + }); + } + + public function quit(): void + { + $this->cancelTimer(); + if (! $this->process->isRunning()) { + return; + } + + foreach ($this->process->pipes as $pipe) { + $pipe->close(); + } + + $this->encoder->end(); + } + + public function bindConnection(Decoder $decoder, Encoder $encoder): void + { + $decoder->on(ReactEvent::DATA, function (array $json): void { + $this->cancelTimer(); + if ($json[ReactCommand::ACTION] !== Action::RESULT) { + return; + } + + $onData = $this->onData; + $onData($json[Content::RESULT]); + }); + $this->encoder = $encoder; + + $decoder->on(ReactEvent::ERROR, function (Throwable $throwable): void { + $onError = $this->onError; + $onError($throwable); + }); + + $encoder->on(ReactEvent::ERROR, function (Throwable $throwable): void { + $onError = $this->onError; + $onError($throwable); + }); + } + + private function cancelTimer(): void + { + if (! $this->timer instanceof TimerInterface) { + return; + } + + $this->loop->cancelTimer($this->timer); + $this->timer = null; + } +} diff --git a/src/Parallel/ValueObject/ProcessPool.php b/src/Parallel/ValueObject/ProcessPool.php new file mode 100644 index 00000000000..54794b2ef98 --- /dev/null +++ b/src/Parallel/ValueObject/ProcessPool.php @@ -0,0 +1,67 @@ + + */ + private array $processes = []; + + public function __construct( + private readonly TcpServer $tcpServer + ) { + } + + public function getProcess(string $identifier): ParallelProcess + { + if (! \array_key_exists($identifier, $this->processes)) { + throw new ParallelShouldNotHappenException(\sprintf('Process "%s" not found.', $identifier)); + } + + return $this->processes[$identifier]; + } + + public function attachProcess(string $identifier, ParallelProcess $parallelProcess): void + { + $this->processes[$identifier] = $parallelProcess; + } + + public function tryQuitProcess(string $identifier): void + { + if (! \array_key_exists($identifier, $this->processes)) { + return; + } + + $this->quitProcess($identifier); + } + + public function quitProcess(string $identifier): void + { + $parallelProcess = $this->getProcess($identifier); + $parallelProcess->quit(); + + unset($this->processes[$identifier]); + if ($this->processes !== []) { + return; + } + + $this->tcpServer->close(); + } + + public function quitAll(): void + { + foreach (\array_keys($this->processes) as $identifier) { + $this->quitProcess($identifier); + } + } +} diff --git a/src/Parallel/ValueObject/Schedule.php b/src/Parallel/ValueObject/Schedule.php new file mode 100644 index 00000000000..4128d74fb69 --- /dev/null +++ b/src/Parallel/ValueObject/Schedule.php @@ -0,0 +1,34 @@ +> $jobs + */ + public function __construct( + private readonly int $numberOfProcesses, + private readonly array $jobs + ) { + } + + public function getNumberOfProcesses(): int + { + return $this->numberOfProcesses; + } + + /** + * @return array> + */ + public function getJobs(): array + { + return $this->jobs; + } +} diff --git a/src/Parallel/WorkerRunner.php b/src/Parallel/WorkerRunner.php index 4991517c4a0..e4c71a20fe1 100644 --- a/src/Parallel/WorkerRunner.php +++ b/src/Parallel/WorkerRunner.php @@ -7,14 +7,14 @@ use Clue\React\NDJson\Decoder; use Clue\React\NDJson\Encoder; use Symplify\EasyCodingStandard\Application\SingleFileProcessor; +use Symplify\EasyCodingStandard\Parallel\Enum\Action; +use Symplify\EasyCodingStandard\Parallel\Enum\Content; +use Symplify\EasyCodingStandard\Parallel\Enum\ReactCommand; +use Symplify\EasyCodingStandard\Parallel\Enum\ReactEvent; use Symplify\EasyCodingStandard\Parallel\ValueObject\Bridge; use Symplify\EasyCodingStandard\Utils\ParametersMerger; use Symplify\EasyCodingStandard\ValueObject\Configuration; use Symplify\EasyCodingStandard\ValueObject\Error\SystemError; -use Symplify\EasyParallel\Enum\Action; -use Symplify\EasyParallel\Enum\Content; -use Symplify\EasyParallel\Enum\ReactCommand; -use Symplify\EasyParallel\Enum\ReactEvent; use Throwable; final readonly class WorkerRunner diff --git a/src/SniffRunner/ValueObject/Error/CodingStandardError.php b/src/SniffRunner/ValueObject/Error/CodingStandardError.php index 82f356b959a..c17aa4f1e08 100644 --- a/src/SniffRunner/ValueObject/Error/CodingStandardError.php +++ b/src/SniffRunner/ValueObject/Error/CodingStandardError.php @@ -4,8 +4,8 @@ namespace Symplify\EasyCodingStandard\SniffRunner\ValueObject\Error; +use Symplify\EasyCodingStandard\Parallel\Contract\SerializableInterface; use Symplify\EasyCodingStandard\Parallel\ValueObject\Name; -use Symplify\EasyParallel\Contract\SerializableInterface; final readonly class CodingStandardError implements SerializableInterface { diff --git a/src/ValueObject/Error/FileDiff.php b/src/ValueObject/Error/FileDiff.php index e962384e0e6..dc72810fff2 100644 --- a/src/ValueObject/Error/FileDiff.php +++ b/src/ValueObject/Error/FileDiff.php @@ -6,8 +6,8 @@ use PHP_CodeSniffer\Sniffs\Sniff; use PhpCsFixer\Fixer\FixerInterface; +use Symplify\EasyCodingStandard\Parallel\Contract\SerializableInterface; use Symplify\EasyCodingStandard\Parallel\ValueObject\Name; -use Symplify\EasyParallel\Contract\SerializableInterface; final class FileDiff implements SerializableInterface { diff --git a/src/ValueObject/Error/SystemError.php b/src/ValueObject/Error/SystemError.php index ac756810bd7..122cec38d4c 100644 --- a/src/ValueObject/Error/SystemError.php +++ b/src/ValueObject/Error/SystemError.php @@ -4,8 +4,8 @@ namespace Symplify\EasyCodingStandard\ValueObject\Error; +use Symplify\EasyCodingStandard\Parallel\Contract\SerializableInterface; use Symplify\EasyCodingStandard\Parallel\ValueObject\Name; -use Symplify\EasyParallel\Contract\SerializableInterface; final readonly class SystemError implements SerializableInterface { From 3ecf68ab5e89be8d5369819cd43ecd401321f747 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 20 Jun 2026 11:05:18 +0200 Subject: [PATCH 2/2] cleanup --- CLAUDE.md | 6 +----- phpstan.neon | 2 +- .../CommandLine/WorkerCommandLineFactory.php | 5 +---- src/Parallel/CpuCoreCountProvider.php | 8 +++----- src/Parallel/Enum/Action.php | 15 +++----------- src/Parallel/Enum/Content.php | 10 ++-------- src/Parallel/Enum/ReactCommand.php | 10 ++-------- src/Parallel/Enum/ReactEvent.php | 20 ++++--------------- src/Parallel/ScheduleFactory.php | 3 +++ src/Parallel/ValueObject/ParallelProcess.php | 9 +++++---- src/Parallel/ValueObject/Schedule.php | 6 +++--- 11 files changed, 28 insertions(+), 66 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index e3bcfea1130..c52eef30369 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -31,7 +31,7 @@ Memory limit for PHPStan and Rector is `1G` (already set in composer scripts). ## Architecture -- `src/Config/ECSConfig.php` — Illuminate container subclass, low-level rule registration (`rule()`, `ruleWithConfiguration()`, `sets()`, `import()`). Auto-tags Sniff/FixerInterface/OutputFormatterInterface bindings. +- `src/Config/ECSConfig.php` — `Entropy\Container\Container` subclass, low-level rule registration (`rule()`, `ruleWithConfiguration()`, `sets()`, `import()`). Auto-tags Sniff/FixerInterface/OutputFormatterInterface bindings. - `src/Configuration/ECSConfigBuilder.php` — fluent user-facing API (`withRules`, `withSets`, `withPreparedSets`, `withPhpCsFixerSets`, `withSpacesLevel`, …). Returned by `ECSConfig::configure()`. `__invoke(ECSConfig)` flushes the builder state into the container. - `config/set/common/*.php` — prepared rule sets (spaces, arrays, namespaces, docblock, etc.); each returns a closure consumed by `ECSConfig::import()`. - `src/Config/Level/` — gradual-adoption levels (e.g. `SpacesLevel`). Each level class exposes `RULES` (ordered safest → most invasive) and optionally `RULE_CONFIGURATIONS`. @@ -50,10 +50,6 @@ Memory limit for PHPStan and Rector is `1G` (already set in composer scripts). - Don't introduce new comments unless they explain a non-obvious why; well-named identifiers should carry meaning. - Don't add backwards-compat shims, dead re-exports, or features that aren't required by the task. -## Patched dependency - -`illuminate/container` is patched via `patches/illuminate-container-container-php.patch` (cweagans/composer-patches). Don't update the package without re-checking the patch. - ## Don't - Don't bypass `phpstan`, `rector`, or `check-cs` with skip comments unless the user asks for it. diff --git a/phpstan.neon b/phpstan.neon index 917a25e542d..d36605a3466 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -44,7 +44,7 @@ parameters: # set above - path: src/Parallel/Application/ParallelFileProcessor.php - message: '#Cannot call method (.*?)\(\) on Symplify\\EasyParallel\\ValueObject\\ProcessPool\|null#' + message: '#Cannot call method (.*?)\(\) on Symplify\\EasyCodingStandard\\Parallel\\ValueObject\\ProcessPool\|null#' - '#Method Symplify\\EasyCodingStandard\\Application\\SingleFileProcessor\:\:processFilePath\(\) should return array\{file_diffs\?\: array, coding_standard_errors\?\: array\} but returns array<(.*?), array>#' diff --git a/src/Parallel/CommandLine/WorkerCommandLineFactory.php b/src/Parallel/CommandLine/WorkerCommandLineFactory.php index 879785f7838..c16fb0c0384 100644 --- a/src/Parallel/CommandLine/WorkerCommandLineFactory.php +++ b/src/Parallel/CommandLine/WorkerCommandLineFactory.php @@ -6,10 +6,7 @@ final class WorkerCommandLineFactory { - /** - * @var string - */ - private const OPTION_DASHES = '--'; + private const string OPTION_DASHES = '--'; /** * @param array $workerOptionValues option name => value, mirrored to the worker process diff --git a/src/Parallel/CpuCoreCountProvider.php b/src/Parallel/CpuCoreCountProvider.php index f2c23fc9f05..3b38997410e 100644 --- a/src/Parallel/CpuCoreCountProvider.php +++ b/src/Parallel/CpuCoreCountProvider.php @@ -9,15 +9,13 @@ final class CpuCoreCountProvider { - /** - * @var int - */ - private const DEFAULT_CORE_COUNT = 2; + private const int DEFAULT_CORE_COUNT = 2; public function provide(): int { try { - return (new CpuCoreCounter())->getCount(); + return new CpuCoreCounter() + ->getCount(); } catch (NumberOfCpuCoreNotFound) { return self::DEFAULT_CORE_COUNT; } diff --git a/src/Parallel/Enum/Action.php b/src/Parallel/Enum/Action.php index 7dfff2da86a..a2bd1fa606c 100644 --- a/src/Parallel/Enum/Action.php +++ b/src/Parallel/Enum/Action.php @@ -6,18 +6,9 @@ final class Action { - /** - * @var string - */ - public const HELLO = 'hello'; + public const string HELLO = 'hello'; - /** - * @var string - */ - public const MAIN = 'main'; + public const string MAIN = 'main'; - /** - * @var string - */ - public const RESULT = 'result'; + public const string RESULT = 'result'; } diff --git a/src/Parallel/Enum/Content.php b/src/Parallel/Enum/Content.php index df399a8f477..2d67902d144 100644 --- a/src/Parallel/Enum/Content.php +++ b/src/Parallel/Enum/Content.php @@ -6,13 +6,7 @@ final class Content { - /** - * @var string - */ - public const RESULT = 'result'; + public const string RESULT = 'result'; - /** - * @var string - */ - public const FILES = 'files'; + public const string FILES = 'files'; } diff --git a/src/Parallel/Enum/ReactCommand.php b/src/Parallel/Enum/ReactCommand.php index 0d98c31debb..73951f4ed4c 100644 --- a/src/Parallel/Enum/ReactCommand.php +++ b/src/Parallel/Enum/ReactCommand.php @@ -6,13 +6,7 @@ final class ReactCommand { - /** - * @var string - */ - public const ACTION = 'action'; + public const string ACTION = 'action'; - /** - * @var string - */ - public const IDENTIFIER = 'identifier'; + public const string IDENTIFIER = 'identifier'; } diff --git a/src/Parallel/Enum/ReactEvent.php b/src/Parallel/Enum/ReactEvent.php index c96063eeb67..6f50d207676 100644 --- a/src/Parallel/Enum/ReactEvent.php +++ b/src/Parallel/Enum/ReactEvent.php @@ -6,23 +6,11 @@ final class ReactEvent { - /** - * @var string - */ - public const EXIT = 'exit'; + public const string EXIT = 'exit'; - /** - * @var string - */ - public const DATA = 'data'; + public const string DATA = 'data'; - /** - * @var string - */ - public const ERROR = 'error'; + public const string ERROR = 'error'; - /** - * @var string - */ - public const CONNECTION = 'connection'; + public const string CONNECTION = 'connection'; } diff --git a/src/Parallel/ScheduleFactory.php b/src/Parallel/ScheduleFactory.php index caed74389fd..8274b457e94 100644 --- a/src/Parallel/ScheduleFactory.php +++ b/src/Parallel/ScheduleFactory.php @@ -5,6 +5,7 @@ namespace Symplify\EasyCodingStandard\Parallel; use Symplify\EasyCodingStandard\Parallel\ValueObject\Schedule; +use Webmozart\Assert\Assert; /** * Used from @@ -17,6 +18,8 @@ final class ScheduleFactory */ public function create(int $cpuCores, int $jobSize, int $maxNumberOfProcesses, array $files): Schedule { + Assert::positiveInteger($jobSize); + $jobs = array_chunk($files, $jobSize); $numberOfProcesses = min(count($jobs), $cpuCores); diff --git a/src/Parallel/ValueObject/ParallelProcess.php b/src/Parallel/ValueObject/ParallelProcess.php index d3e10b09a7e..2b71d87788b 100644 --- a/src/Parallel/ValueObject/ParallelProcess.php +++ b/src/Parallel/ValueObject/ParallelProcess.php @@ -73,19 +73,20 @@ public function start(callable $onData, callable $onError, callable $onExit): vo $this->onError = $onError; $this->process->on(ReactEvent::EXIT, function ($exitCode) use ($onExit): void { - if ($this->stdErr === null) { + $stdErr = $this->stdErr; + if ($stdErr === null) { throw new ParallelShouldNotHappenException(); } $this->cancelTimer(); - rewind($this->stdErr); + rewind($stdErr); /** @var string $streamContents */ - $streamContents = stream_get_contents($this->stdErr); + $streamContents = stream_get_contents($stdErr); $onExit($exitCode, $streamContents); - fclose($this->stdErr); + fclose($stdErr); }); } diff --git a/src/Parallel/ValueObject/Schedule.php b/src/Parallel/ValueObject/Schedule.php index 4128d74fb69..2bf298fee9c 100644 --- a/src/Parallel/ValueObject/Schedule.php +++ b/src/Parallel/ValueObject/Schedule.php @@ -8,14 +8,14 @@ * From * https://github.com/phpstan/phpstan-src/commit/9124c66dcc55a222e21b1717ba5f60771f7dda92#diff-bc84213b079ef3456caece03c00ba34c07886dcae12180cd1192fbb223d65b15 */ -final class Schedule +final readonly class Schedule { /** * @param array> $jobs */ public function __construct( - private readonly int $numberOfProcesses, - private readonly array $jobs + private int $numberOfProcesses, + private array $jobs ) { }