From f7e402d75b5c0970e562080161220f80c5385d16 Mon Sep 17 00:00:00 2001 From: sji Date: Wed, 15 Dec 2021 03:30:41 +0900 Subject: [PATCH] use igbinary for communication between processes if possible (depending on the configuration) --- src/Psalm/Internal/Codebase/Analyzer.php | 1 + src/Psalm/Internal/Codebase/Scanner.php | 1 + src/Psalm/Internal/Fork/Pool.php | 29 +++++++++++++++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Psalm/Internal/Codebase/Analyzer.php b/src/Psalm/Internal/Codebase/Analyzer.php index 6ad8333bca3..424508ff544 100644 --- a/src/Psalm/Internal/Codebase/Analyzer.php +++ b/src/Psalm/Internal/Codebase/Analyzer.php @@ -424,6 +424,7 @@ function (array $issues): void { // Run analysis one file at a time, splitting the set of // files up among a given number of child processes. $pool = new Pool( + $this->config, $process_file_paths, function (): void { $project_analyzer = ProjectAnalyzer::getInstance(); diff --git a/src/Psalm/Internal/Codebase/Scanner.php b/src/Psalm/Internal/Codebase/Scanner.php index f9c72f48e3d..f14550c8a35 100644 --- a/src/Psalm/Internal/Codebase/Scanner.php +++ b/src/Psalm/Internal/Codebase/Scanner.php @@ -360,6 +360,7 @@ function (int $_, string $file_path) use ($filetype_scanners, $files_to_deep_sca // Run scanning one file at a time, splitting the set of // files up among a given number of child processes. $pool = new Pool( + $this->config, $process_file_paths, function (): void { $this->progress->debug('Initialising forked process for scanning' . PHP_EOL); diff --git a/src/Psalm/Internal/Fork/Pool.php b/src/Psalm/Internal/Fork/Pool.php index 19d3f6c543f..94cbe0b7c11 100644 --- a/src/Psalm/Internal/Fork/Pool.php +++ b/src/Psalm/Internal/Fork/Pool.php @@ -3,6 +3,7 @@ use Closure; use Exception; +use Psalm\Config; use Throwable; use function array_fill_keys; @@ -24,6 +25,8 @@ use function fwrite; use function get_class; use function gettype; +use function igbinary_serialize; +use function igbinary_unserialize; use function in_array; use function ini_get; use function pcntl_fork; @@ -69,6 +72,9 @@ class Pool private const EXIT_SUCCESS = 0; private const EXIT_FAILURE = 1; + /** @var Config */ + private $config; + /** @var int[] */ private $child_pid_list = []; @@ -88,6 +94,7 @@ class Pool . 'Relevant info: https://bugs.php.net/bug.php?id=77260'; /** + * @param Config $config * @param array> $process_task_data_iterator * An array of task data items to be divided up among the * workers. The size of this is the number of forked processes. @@ -104,6 +111,7 @@ class Pool * @psalm-suppress MixedAssignment */ public function __construct( + Config $config, array $process_task_data_iterator, Closure $startup_closure, Closure $task_closure, @@ -112,6 +120,7 @@ public function __construct( ) { $pool_size = count($process_task_data_iterator); $this->task_done_closure = $task_done_closure; + $this->config = $config; assert( $pool_size > 1, @@ -201,7 +210,12 @@ public function __construct( $task_result = $task_closure($i, $task_data); $task_done_message = new ForkTaskDoneMessage($task_result); - $serialized_message = $task_done_buffer . base64_encode(serialize($task_done_message)) . "\n"; + if ($this->config->use_igbinary) { + $encoded_message = base64_encode(igbinary_serialize($task_done_message)); + } else { + $encoded_message = base64_encode(serialize($task_done_message)); + } + $serialized_message = $task_done_buffer . $encoded_message . "\n"; if (strlen($serialized_message) > 200) { $bytes_written = @fwrite($write_stream, $serialized_message); @@ -233,7 +247,12 @@ public function __construct( ); } - $serialized_message = $task_done_buffer . base64_encode(serialize($process_done_message)) . "\n"; + if ($this->config->use_igbinary) { + $encoded_message = base64_encode(igbinary_serialize($process_done_message)); + } else { + $encoded_message = base64_encode(serialize($process_done_message)); + } + $serialized_message = $task_done_buffer . $encoded_message . "\n"; $bytes_to_write = strlen($serialized_message); $bytes_written = 0; @@ -356,7 +375,11 @@ private function readResultsFromChildren(): array $content[(int)$file] = array_pop($serialized_messages); foreach ($serialized_messages as $serialized_message) { - $message = unserialize(base64_decode($serialized_message, true)); + if ($this->config->use_igbinary) { + $message = igbinary_unserialize(base64_decode($serialized_message, true)); + } else { + $message = unserialize(base64_decode($serialized_message, true)); + } if ($message instanceof ForkProcessDoneMessage) { $terminationMessages[] = $message->data;