Skip to content

Commit

Permalink
Support cache in parallel analysis
Browse files Browse the repository at this point in the history
Cache check is done during file iteration - if file is in cache and wasn't changed, then it's skip by iterator and doesn't even go to the worker. That's why `ReadonlyCacheManager` used on worker's side is a bit superfluous, but I thought it's safer to use it instead of `NullCacheManager`.

Anyway, each file is stored to cache when worker reports analysis result to the parallelisation operator, so it's basically similar to sequential analysis, because file write is done only in one process.
  • Loading branch information
Wirone committed Feb 7, 2024
1 parent 8577ee3 commit 12e893d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/Console/Command/WorkerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use PhpCsFixer\Error\ErrorsManager;
use PhpCsFixer\FixerFileProcessedEvent;
use PhpCsFixer\Runner\Parallel\ParallelConfig;
use PhpCsFixer\Runner\Parallel\ReadonlyCacheManager;
use PhpCsFixer\Runner\Runner;
use PhpCsFixer\ToolInfoInterface;
use React\EventLoop\StreamSelectLoop;
Expand Down Expand Up @@ -50,6 +51,7 @@ final class WorkerCommand extends Command
private ConfigurationResolver $configurationResolver;
private ErrorsManager $errorsManager;
private EventDispatcherInterface $eventDispatcher;
private ReadonlyCacheManager $readonlyCacheManager;

/** @var array<int, FixerFileProcessedEvent> */
private array $events;
Expand Down Expand Up @@ -220,6 +222,8 @@ private function createRunner(InputInterface $input): Runner
$this->toolInfo
);

$this->readonlyCacheManager = new ReadonlyCacheManager($this->configurationResolver->getCacheManager());

return new Runner(
null, // Paths are known when parallelisation server requests new chunk, not now
$this->configurationResolver->getFixers(),
Expand All @@ -228,7 +232,7 @@ private function createRunner(InputInterface $input): Runner
$this->errorsManager,
$this->configurationResolver->getLinter(),
$this->configurationResolver->isDryRun(),
$this->configurationResolver->getCacheManager(),
$this->readonlyCacheManager,
$this->configurationResolver->getDirectory(),
$this->configurationResolver->shouldStopOnViolation(),
ParallelConfig::sequential(), // IMPORTANT! Worker must run in sequential mode
Expand Down
34 changes: 34 additions & 0 deletions src/Runner/Parallel/ReadonlyCacheManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

/*
* This file is part of PHP CS Fixer.
*
* (c) Fabien Potencier <[email protected]>
* Dariusz Rumiński <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace PhpCsFixer\Runner\Parallel;

use PhpCsFixer\Cache\CacheManagerInterface;

final class ReadonlyCacheManager implements CacheManagerInterface
{
private CacheManagerInterface $cacheManager;

public function __construct(CacheManagerInterface $cacheManager)
{
$this->cacheManager = $cacheManager;
}

public function needFixing(string $file, string $fileContent): bool
{
return $this->cacheManager->needFixing($file, $fileContent);
}

public function setFile(string $file, string $fileContent): void {}
}
1 change: 1 addition & 0 deletions src/Runner/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ function (array $analysisResult) use ($processPool, $process, $identifier, $file
}
// Dispatch an event for each file processed and dispatch its status (required for progress output)
$this->dispatchEvent(FixerFileProcessedEvent::NAME, new FixerFileProcessedEvent($result['status']));
$this->cacheManager->setFile($file, file_get_contents($this->directory->getAbsolutePath().\DIRECTORY_SEPARATOR.$file));

foreach ($result['errors'] ?? [] as $workerError) {
$error = new Error(
Expand Down

0 comments on commit 12e893d

Please sign in to comment.