From 3400819f1e8ecb08bbc643861058df86e889b359 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Tue, 23 Nov 2021 19:36:45 +0000 Subject: [PATCH] Limit the number of hh_client processes --- src/Linters/HHClientLinter.hack | 15 ++++++------ src/__Private/ProcessExecutionQueue.hack | 30 +++++++++-------------- src/__Private/ProcessExecutionQueues.hack | 21 ++++++++++++++++ src/entrypoints.hack | 2 +- 4 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 src/__Private/ProcessExecutionQueues.hack diff --git a/src/Linters/HHClientLinter.hack b/src/Linters/HHClientLinter.hack index 692c10019..debf849d0 100644 --- a/src/Linters/HHClientLinter.hack +++ b/src/Linters/HHClientLinter.hack @@ -62,13 +62,14 @@ final class HHClientLinter implements Linter { public async function getLintErrorsAsync( ): Awaitable> { - $lines = await __Private\execute_async( - 'hh_client', - '--lint', - $this->getFile()->getPath(), - '--json', - '--from', - 'hhast', + $lines = await __Private\ProcessExecutionQueues::HH_CLIENT->waitForAsync( + vec[ + '--lint', + $this->getFile()->getPath(), + '--json', + '--from', + 'hhast', + ], ); $hh_client_lint_result = TypeAssert\matches( \json_decode( diff --git a/src/__Private/ProcessExecutionQueue.hack b/src/__Private/ProcessExecutionQueue.hack index 64e103b02..a981885c9 100644 --- a/src/__Private/ProcessExecutionQueue.hack +++ b/src/__Private/ProcessExecutionQueue.hack @@ -12,33 +12,25 @@ namespace Facebook\HHAST\__Private; use namespace HH\Lib\Async; final class ProcessExecutionQueue { - private Async\Semaphore, vec> $impl; - protected function __construct(int $limit, string $process_name) { - $this->impl = new Async\Semaphore( - $limit, - async (vec $args) ==> await execute_async($process_name, ...$args), - ); - } - - // Random number; it might seem high, but it's likely that `hh_parse` will - // execute quick enough that most of the processes are waiting to be cleaned - // up - const int HH_PARSE_LIMIT = 32; - const int HH_CLIENT_LIMIT = 32; <<__Memoize>> - public static function getHHParserQueue(): this { - return new self(self::HH_PARSE_LIMIT, 'hh_parse'); + private function impl(): Async\Semaphore, vec> { + return new Async\Semaphore( + $this->limit, + async (vec $args) ==> + await execute_async($this->process_name, ...$args), + ); } - <<__Memoize>> - public static function getHHClientQueue(): this { - return new self(self::HH_CLIENT_LIMIT, 'hh_client'); + public function __construct( + private int $limit, + private string $process_name, + )[] { } public async function waitForAsync( vec $args, ): Awaitable> { - return await $this->impl->waitForAsync($args); + return await $this->impl()->waitForAsync($args); } } diff --git a/src/__Private/ProcessExecutionQueues.hack b/src/__Private/ProcessExecutionQueues.hack new file mode 100644 index 000000000..434567c69 --- /dev/null +++ b/src/__Private/ProcessExecutionQueues.hack @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +namespace Facebook\HHAST\__Private; + +enum class ProcessExecutionQueues: ProcessExecutionQueue { + + // Random number; it might seem high, but it's likely that `hh_parse` will + // execute quick enough that most of the processes are waiting to be cleaned + // up + ProcessExecutionQueue HH_CLIENT = + new ProcessExecutionQueue(32, 'hh_client'); + ProcessExecutionQueue HH_PARSE = new ProcessExecutionQueue(32, 'hh_parse'); + +} diff --git a/src/entrypoints.hack b/src/entrypoints.hack index 183f77d69..2cdbfbfbc 100644 --- a/src/entrypoints.hack +++ b/src/entrypoints.hack @@ -30,7 +30,7 @@ async function from_file_async( ); try { - $results = await __Private\ProcessExecutionQueue::getHHParserQueue() + $results = await __Private\ProcessExecutionQueues::HH_PARSE ->waitForAsync($args); } catch (__Private\SubprocessException $e) { throw new HHParseError(