Skip to content

Commit

Permalink
Show combined memory usage in parallel mode
Browse files Browse the repository at this point in the history
  • Loading branch information
janedbal authored Jan 3, 2023
1 parent cde53d1 commit 2556918
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 26 deletions.
2 changes: 2 additions & 0 deletions src/Analyser/Analyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use function array_fill_keys;
use function array_merge;
use function count;
use function memory_get_peak_usage;
use function sprintf;

class Analyser
Expand Down Expand Up @@ -110,6 +111,7 @@ public function analyse(
$internalErrorsCount === 0 ? $dependencies : null,
$exportedNodes,
$reachedInternalErrorsCountLimit,
memory_get_peak_usage(true),
);
}

Expand Down
6 changes: 6 additions & 0 deletions src/Analyser/AnalyserResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function __construct(
private ?array $dependencies,
private array $exportedNodes,
private bool $reachedInternalErrorsCountLimit,
private int $peakMemoryUsageBytes,
)
{
$this->unorderedErrors = $errors;
Expand Down Expand Up @@ -97,4 +98,9 @@ public function hasReachedInternalErrorsCountLimit(): bool
return $this->reachedInternalErrorsCountLimit;
}

public function getPeakMemoryUsageBytes(): int
{
return $this->peakMemoryUsageBytes;
}

}
1 change: 1 addition & 0 deletions src/Analyser/ResultCache/ResultCacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ public function process(AnalyserResult $analyserResult, ResultCache $resultCache
$dependencies,
$exportedNodes,
$analyserResult->hasReachedInternalErrorsCountLimit(),
$analyserResult->getPeakMemoryUsageBytes(),
), $saved);
}

Expand Down
7 changes: 6 additions & 1 deletion src/Command/AnalyseApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public function analyse(
$internalErrors = [];
$collectedData = [];
$savedResultCache = false;
$memoryUsageBytes = memory_get_peak_usage(true);
if ($errorOutput->isDebug()) {
$errorOutput->writeLineFormatted('Result cache was not saved because of ignoredErrorHelperResult errors.');
}
Expand All @@ -97,6 +98,7 @@ public function analyse(
$intermediateAnalyserResult->getDependencies(),
$intermediateAnalyserResult->getExportedNodes(),
$intermediateAnalyserResult->hasReachedInternalErrorsCountLimit(),
$intermediateAnalyserResult->getPeakMemoryUsageBytes(),
);
}

Expand All @@ -105,6 +107,8 @@ public function analyse(
$internalErrors = $analyserResult->getInternalErrors();
$errors = $analyserResult->getErrors();
$hasInternalErrors = count($internalErrors) > 0 || $analyserResult->hasReachedInternalErrorsCountLimit();
$memoryUsageBytes = $analyserResult->getPeakMemoryUsageBytes();

if (!$hasInternalErrors) {
foreach ($this->getCollectedDataErrors($analyserResult->getCollectedData()) as $error) {
$errors[] = $error;
Expand Down Expand Up @@ -139,6 +143,7 @@ public function analyse(
$defaultLevelUsed,
$projectConfigFile,
$savedResultCache,
$memoryUsageBytes,
);
}

Expand Down Expand Up @@ -195,7 +200,7 @@ private function runAnalyser(
$errorOutput->getStyle()->progressStart($allAnalysedFilesCount);
$errorOutput->getStyle()->progressAdvance($allAnalysedFilesCount);
$errorOutput->getStyle()->progressFinish();
return new AnalyserResult([], [], [], [], [], false);
return new AnalyserResult([], [], [], [], [], false, memory_get_peak_usage(true));
}

if (!$debug) {
Expand Down
30 changes: 16 additions & 14 deletions src/Command/AnalyseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

if ($generateBaselineFile === null && $allowEmptyBaseline) {
$inceptionResult->getStdOutput()->getStyle()->error('You must pass the --generate-baseline option alongside --allow-empty-baseline.');
return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, null);
}

$errorOutput = $inceptionResult->getErrorOutput();
Expand Down Expand Up @@ -200,13 +200,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$baselineExtension = pathinfo($generateBaselineFile, PATHINFO_EXTENSION);
if ($baselineExtension === '') {
$inceptionResult->getStdOutput()->getStyle()->error(sprintf('Baseline filename must have an extension, %s provided instead.', pathinfo($generateBaselineFile, PATHINFO_BASENAME)));
return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, null);
}

if ($baselineExtension !== 'neon') {
$inceptionResult->getStdOutput()->getStyle()->error(sprintf('Baseline filename extension must be .neon, .%s was used instead.', $baselineExtension));

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, null);
}
}

Expand Down Expand Up @@ -267,7 +267,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$previous = $previous->getPrevious();
}

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, null);
}

throw $t;
Expand All @@ -278,12 +278,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$inceptionResult->getStdOutput()->getStyle()->error('No errors were found during the analysis. Baseline could not be generated.');
$inceptionResult->getStdOutput()->writeLineFormatted('To allow generating empty baselines, pass <fg=cyan>--allow-empty-baseline</> option.');

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}
if ($analysisResult->hasInternalErrors()) {
$inceptionResult->getStdOutput()->getStyle()->error('An internal error occurred. Baseline could not be generated. Re-run PHPStan without --generate-baseline to see what\'s going on.');

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}

$baselineFileDirectory = dirname($generateBaselineFile);
Expand All @@ -308,7 +308,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($mkdirResult === false) {
$inceptionResult->getStdOutput()->writeLineFormatted(sprintf('Failed to create directory "%s".', $baselineFileDirectory));

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}
}

Expand All @@ -317,7 +317,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
} catch (CouldNotWriteFileException $e) {
$inceptionResult->getStdOutput()->writeLineFormatted($e->getMessage());

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}

$errorsCount = 0;
Expand Down Expand Up @@ -348,15 +348,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$inceptionResult->getStdOutput()->getStyle()->warning($message . "\nSome errors could not be put into baseline. Re-run PHPStan and fix them.");
}

return $inceptionResult->handleReturn(0);
return $inceptionResult->handleReturn(0, $analysisResult->getPeakMemoryUsageBytes());
}

if ($fix) {
$ciDetector = new CiDetector();
if ($ciDetector->isCiDetected()) {
$inceptionResult->getStdOutput()->writeLineFormatted('PHPStan Pro can\'t run in CI environment yet. Stay tuned!');

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}
$container->getByType(ResultCacheClearer::class)->clearTemporaryCaches();
$hasInternalErrors = $analysisResult->hasInternalErrors();
Expand All @@ -379,6 +379,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$analysisResult->isDefaultLevelUsed(),
$analysisResult->getProjectConfigFile(),
$analysisResult->isResultCacheSaved(),
$analysisResult->getPeakMemoryUsageBytes(),
);

$stdOutput = $inceptionResult->getStdOutput();
Expand All @@ -395,15 +396,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$stdOutput->writeLineFormatted(sprintf('nonIgnorableErrorsByExceptionCount: %d', count($nonIgnorableErrorsByException)));
}

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}

if (!$analysisResult->isResultCacheSaved() && !$onlyFiles) {
// this can happen only if there are some regex-related errors in ignoreErrors configuration
$stdOutput = $inceptionResult->getStdOutput();
if (count($analysisResult->getFileSpecificErrors()) > 0) {
$stdOutput->getStyle()->error('Unknown error. Please report this as a bug.');
return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}

$stdOutput->getStyle()->error('PHPStan Pro can\'t be launched because of these errors:');
Expand All @@ -418,10 +419,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$stdOutput->writeLineFormatted('Result cache was not saved.');
}

return $inceptionResult->handleReturn(1);
return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes());
}

$inceptionResult->handleReturn(0);
$inceptionResult->handleReturn(0, $analysisResult->getPeakMemoryUsageBytes());

/** @var FixerApplication $fixerApplication */
$fixerApplication = $container->getByType(FixerApplication::class);
Expand All @@ -443,6 +444,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

return $inceptionResult->handleReturn(
$errorFormatter->formatErrors($analysisResult, $inceptionResult->getStdOutput()),
$analysisResult->getPeakMemoryUsageBytes(),
);
}

Expand Down
3 changes: 2 additions & 1 deletion src/Command/AnalyserRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use function count;
use function function_exists;
use function is_file;
use function memory_get_peak_usage;

class AnalyserRunner
{
Expand Down Expand Up @@ -48,7 +49,7 @@ public function runAnalyser(
{
$filesCount = count($files);
if ($filesCount === 0) {
return new AnalyserResult([], [], [], [], [], false);
return new AnalyserResult([], [], [], [], [], false, memory_get_peak_usage(true));
}

$schedule = $this->scheduler->scheduleWork($this->cpuCoreCounter->getNumberOfCpuCores(), $files);
Expand Down
6 changes: 6 additions & 0 deletions src/Command/AnalysisResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function __construct(
private bool $defaultLevelUsed,
private ?string $projectConfigFile,
private bool $savedResultCache,
private int $peakMemoryUsageBytes,
)
{
usort(
Expand Down Expand Up @@ -123,4 +124,9 @@ public function isResultCacheSaved(): bool
return $this->savedResultCache;
}

public function getPeakMemoryUsageBytes(): int
{
return $this->peakMemoryUsageBytes;
}

}
1 change: 1 addition & 0 deletions src/Command/ErrorFormatter/TableErrorFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function formatErrors(

if (!$analysisResult->hasErrors() && !$analysisResult->hasWarnings()) {
$style->success('No errors');

if ($this->showTipsOfTheDay) {
if ($analysisResult->isDefaultLevelUsed()) {
$output->writeLineFormatted('💡 Tip of the Day:');
Expand Down
30 changes: 30 additions & 0 deletions src/Command/ErrorsConsoleStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ public function createProgressBar(int $max = 0): ProgressBar
{
$this->progressBar = parent::createProgressBar($max);

$format = $this->getProgressBarFormat();
if ($format !== null) {
$this->progressBar->setFormat($format);
}

$ci = $this->isCiDetected();
$this->progressBar->setOverwrite(!$ci);

Expand All @@ -136,6 +141,31 @@ public function createProgressBar(int $max = 0): ProgressBar
return $this->progressBar;
}

private function getProgressBarFormat(): ?string
{
switch ($this->getVerbosity()) {
case OutputInterface::VERBOSITY_NORMAL:
$formatName = ProgressBar::FORMAT_NORMAL;
break;
case OutputInterface::VERBOSITY_VERBOSE:
$formatName = ProgressBar::FORMAT_VERBOSE;
break;
case OutputInterface::VERBOSITY_VERY_VERBOSE:
case OutputInterface::VERBOSITY_DEBUG:
$formatName = ProgressBar::FORMAT_VERY_VERBOSE;
break;
default:
$formatName = null;
break;
}

if ($formatName === null) {
return null;
}

return ProgressBar::getFormatDefinition($formatName);
}

public function progressStart(int $max = 0): void
{
if (!$this->showProgress) {
Expand Down
3 changes: 2 additions & 1 deletion src/Command/FixerApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
use function is_dir;
use function is_file;
use function is_string;
use function memory_get_peak_usage;
use function min;
use function mkdir;
use function parse_url;
Expand Down Expand Up @@ -507,7 +508,7 @@ private function reanalyseAfterFileChanges(
$resultCache = $resultCacheManager->restore($inceptionFiles, false, false, $projectConfigArray, $inceptionResult->getErrorOutput(), $fixerSuggestionId);
if (count($resultCache->getFilesToAnalyse()) === 0) {
$result = $resultCacheManager->process(
new AnalyserResult([], [], [], [], [], false),
new AnalyserResult([], [], [], [], [], false, memory_get_peak_usage(true)),
$resultCache,
$inceptionResult->getErrorOutput(),
false,
Expand Down
1 change: 1 addition & 0 deletions src/Command/FixerWorkerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ private function switchTmpFileInAnalyserResult(
$dependencies,
$exportedNodes,
$analyserResult->hasReachedInternalErrorsCountLimit(),
$analyserResult->getPeakMemoryUsageBytes(),
);
}

Expand Down
7 changes: 3 additions & 4 deletions src/Command/InceptionResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use PHPStan\DependencyInjection\Container;
use PHPStan\Internal\BytesHelper;
use function memory_get_peak_usage;
use function sprintf;

class InceptionResult
Expand Down Expand Up @@ -79,10 +78,10 @@ public function getGenerateBaselineFile(): ?string
return $this->generateBaselineFile;
}

public function handleReturn(int $exitCode): int
public function handleReturn(int $exitCode, ?int $peakMemoryUsageBytes): int
{
if ($this->getErrorOutput()->isVerbose()) {
$this->getErrorOutput()->writeLineFormatted(sprintf('Used memory: %s', BytesHelper::bytes(memory_get_peak_usage(true))));
if ($peakMemoryUsageBytes !== null && $this->getErrorOutput()->isVerbose()) {
$this->getErrorOutput()->writeLineFormatted(sprintf('Used memory: %s', BytesHelper::bytes($peakMemoryUsageBytes)));
}

return $exitCode;
Expand Down
2 changes: 2 additions & 0 deletions src/Command/WorkerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use function is_array;
use function is_bool;
use function is_string;
use function memory_get_peak_usage;
use function sprintf;

class WorkerCommand extends Command
Expand Down Expand Up @@ -242,6 +243,7 @@ private function runWorker(
'result' => [
'errors' => $errors,
'collectedData' => $collectedData,
'memoryUsage' => memory_get_peak_usage(true),
'dependencies' => $dependencies,
'exportedNodes' => $exportedNodes,
'filesCount' => count($files),
Expand Down
Loading

0 comments on commit 2556918

Please sign in to comment.