Skip to content

Commit

Permalink
Configure max processes by free ones
Browse files Browse the repository at this point in the history
  • Loading branch information
yguedidi committed Apr 18, 2023
1 parent 8605fb9 commit 9e7fbed
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 2 deletions.
80 changes: 80 additions & 0 deletions packages-tests/Parallel/ScheduleFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Parallel;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Rector\Core\Kernel\RectorKernel;
use Rector\Parallel\ScheduleFactory;

final class ScheduleFactoryTest extends TestCase
{
private ScheduleFactory $scheduleFactory;

protected function setUp(): void
{
$rectorKernel = new RectorKernel();
$container = $rectorKernel->create();

$this->scheduleFactory = $container->get(ScheduleFactory::class);
}

#[DataProvider('provideData')]
public function test(int $maxNumberOfProcesses, int $fileCount, int $expectedNumberOfProcesses): void
{
$files = array_fill(0, $fileCount, __DIR__ . '/file.php');

$schedule = $this->scheduleFactory->create(4, 20, $maxNumberOfProcesses, $files);

$this->assertSame($expectedNumberOfProcesses, $schedule->getNumberOfProcesses());
}

/**
* @return Iterator<array{int, int, int}>
*/
public static function provideData(): Iterator
{
// default with 4 CPU cores
yield [0, 500, 4];
yield [0, 80, 4];
yield [0, 60, 3];
yield [0, 40, 2];
yield [0, 20, 1];
yield [0, 5, 1];

// force 1 CPU core
yield [1, 500, 1];
yield [1, 80, 1];
yield [1, 60, 1];
yield [1, 40, 1];
yield [1, 20, 1];
yield [1, 5, 1];

// force over real available CPU cores
yield [8, 500, 4];
yield [8, 80, 4];
yield [8, 60, 3];
yield [8, 40, 2];
yield [8, 20, 1];
yield [8, 5, 1];

// preserve 1 CPU core
yield [-1, 500, 3];
yield [-1, 80, 3];
yield [-1, 60, 3];
yield [-1, 40, 2];
yield [-1, 20, 1];
yield [-1, 5, 1];

// preserve over real available CPU cores
yield [-7, 500, 1];
yield [-7, 80, 1];
yield [-7, 60, 1];
yield [-7, 40, 1];
yield [-7, 20, 1];
yield [-7, 5, 1];
}
}
6 changes: 5 additions & 1 deletion packages/Config/RectorConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ public function disableParallel(): void
$parameters->set(Option::PARALLEL, false);
}

public function parallel(int $seconds = 120, int $maxNumberOfProcess = 16, int $jobSize = 20): void
/**
* @param int $maxNumberOfProcess Use 0 for max available CPU cores, a positive number to force a number
* of CPU cores, and a negative one to preserve that number of CPU cores.
*/
public function parallel(int $seconds = 120, int $maxNumberOfProcess = 0, int $jobSize = 20): void
{
$parameters = $this->parameters();
$parameters->set(Option::PARALLEL, true);
Expand Down
36 changes: 36 additions & 0 deletions packages/Parallel/ScheduleFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Rector\Parallel;

use Symplify\EasyParallel\ScheduleFactory as EasyParallelScheduleFactory;
use Symplify\EasyParallel\ValueObject\Schedule;

/**
* @see \Rector\Tests\Parallel\ScheduleFactoryTest
*/
final class ScheduleFactory
{
public function __construct(
private readonly EasyParallelScheduleFactory $easyParallelScheduleFactory,
) {
}

/**
* @param array<string> $files
*/
public function create(int $cpuCores, int $jobSize, int $maxNumberOfProcesses, array $files): Schedule
{
if ($maxNumberOfProcesses < 0) {
$cpuCores = max(1, $cpuCores + $maxNumberOfProcesses);
$maxNumberOfProcesses = 0;
}

if ($maxNumberOfProcesses === 0) {
$maxNumberOfProcesses = $cpuCores;
}

return $this->easyParallelScheduleFactory->create($cpuCores, $jobSize, $maxNumberOfProcesses, $files);
}
}
2 changes: 1 addition & 1 deletion src/Application/ApplicationFileProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
use Rector\Core\ValueObject\Reporting\FileDiff;
use Rector\Core\ValueObjectFactory\Application\FileFactory;
use Rector\Parallel\Application\ParallelFileProcessor;
use Rector\Parallel\ScheduleFactory;
use Rector\Parallel\ValueObject\Bridge;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symplify\EasyParallel\CpuCoreCountProvider;
use Symplify\EasyParallel\Exception\ParallelShouldNotHappenException;
use Symplify\EasyParallel\ScheduleFactory;

final class ApplicationFileProcessor
{
Expand Down

0 comments on commit 9e7fbed

Please sign in to comment.