Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use igbinary for communication between processes if possible #7162

Merged
merged 1 commit into from Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Psalm/Internal/Codebase/Analyzer.php
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions src/Psalm/Internal/Codebase/Scanner.php
Expand Up @@ -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);
Expand Down
29 changes: 26 additions & 3 deletions src/Psalm/Internal/Fork/Pool.php
Expand Up @@ -3,6 +3,7 @@

use Closure;
use Exception;
use Psalm\Config;
use Throwable;

use function array_fill_keys;
Expand All @@ -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;
Expand Down Expand Up @@ -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 = [];

Expand All @@ -88,6 +94,7 @@ class Pool
. 'Relevant info: https://bugs.php.net/bug.php?id=77260';

/**
* @param Config $config
* @param array<int, array<int, mixed>> $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.
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down