Skip to content
This repository has been archived by the owner on Dec 1, 2024. It is now read-only.

Commit

Permalink
Replace ConcurrentAsyncQueue with Async\Semaphore
Browse files Browse the repository at this point in the history
  • Loading branch information
fredemmott committed May 13, 2019
1 parent e136aac commit e2f73e4
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 133 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"require": {
"hhvm": "^4.3",
"hhvm/hsl": "^4.0",
"hhvm/hsl-experimental": "^4.5",
"hhvm/hhvm-autoload": "^2.0.4",
"hhvm/type-assert": "^3.1",
"facebook/hh-clilib": "^2.0.0",
Expand Down
58 changes: 29 additions & 29 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 0 additions & 51 deletions src/__Private/ConcurrentAsyncQueue.hack

This file was deleted.

23 changes: 20 additions & 3 deletions src/__Private/ParserQueue.hack
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,31 @@

namespace Facebook\HHAST\__Private;

final class ParserQueue extends ConcurrentAsyncQueue {
use namespace HH\Lib\Experimental\Async;


final class ParserQueue {
private Async\Semaphore<vec<string>, vec<string>> $impl;
protected function __construct() {
$this->impl = new Async\Semaphore(
self::LIMIT,
async $args ==> await execute_async('hh_parse', ...$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 LIMIT = 32;

<<__Memoize>>
public static function get(): ConcurrentAsyncQueue {
return new ConcurrentAsyncQueue(self::LIMIT);
public static function get(): ParserQueue {
return new ParserQueue();
}

public async function waitForAsync(
vec<string> $args,
): Awaitable<vec<string>> {
return await $this->impl->waitForAsync($args);
}
}
79 changes: 34 additions & 45 deletions src/__Private/codegen/CodegenRelations.hack
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace Facebook\HHAST\__Private;

use namespace HH\Lib\{C, Dict, Keyset, Str, Tuple, Vec};
use namespace HH\Lib\Experimental\Async;
use type Facebook\HackCodegen\{
CodegenFileType,
HackBuilderKeys,
Expand Down Expand Up @@ -38,52 +39,41 @@ final class CodegenRelations extends CodegenBase {
print("Infering relationships, this can take a long time...\n");
$done = new Ref(0);
$start = \microtime(true);
$queue = new ConcurrentAsyncQueue(32);

$relationships = new Ref(dict[]);
$queue = new Async\Semaphore(
/* limit = */ 32,
async $file ==> {
try {
$links = await $this->getRelationsInFileAsync($file);
$new = dict[];
foreach ($links as $key => $children) {
$relationships->v[$key] ??= keyset[];
$new_children = Keyset\diff($children, $relationships->v[$key]);
if ($new_children) {
$new[$key] = $children;
}
}
if ($new) {
await execute_async('hhvm', '-vEval.EnablePHP=true', '-l', $file);
foreach ($new as $key => $children) {
$relationships->v[$key] = Keyset\union(
$relationships->v[$key],
$children,
);
}
}
} catch (\Throwable $_) {
// HHVM and Hack tests intentionally include lots of invalid
// files
} finally {
$done->v++;
}

},
);
await Tuple\from_async(
Dict\map_async(
$files,
async $file ==> {
return await $queue->enqueueAndWaitForAsync(
async () ==> {
try {
$links = await $this->getRelationsInFileAsync($file);
$new = dict[];
foreach ($links as $key => $children) {
$relationships->v[$key] ??= keyset[];
$new_children = Keyset\diff(
$children,
$relationships->v[$key],
);
if ($new_children) {
$new[$key] = $children;
}
}
if ($new) {
await execute_async(
'hhvm',
'-vEval.EnablePHP=true',
'-l',
$file,
);
foreach ($new as $key => $children) {
$relationships->v[$key] = Keyset\union(
$relationships->v[$key],
$children,
);
}
}
} catch (\Throwable $_) {
// HHVM and Hack tests intentionally include lots of invalid
// files
} finally {
$done->v++;
}
},
);
},
),
Dict\map_async($files, async $file ==> await $queue->waitForAsync($file)),
async {
$total = C\count($files);
while ($done->v < $total) {
Expand All @@ -98,13 +88,12 @@ final class CodegenRelations extends CodegenBase {
$end = $start + ($total / $rate);
\fprintf(
\STDERR,
"%d%%\t(%d / %d)\tExpected finish in %ds at %s - concurrency: %d\n",
"%d%%\t(%d / %d)\tExpected finish in %ds at %s\n",
(int)($ratio * 100),
$done->v,
$total,
(int)($end - $now),
\strftime('%H:%M:%S', (int)$end),
$queue->getCurrentConcurrency(),
);
}
},
Expand Down
8 changes: 3 additions & 5 deletions src/entrypoints.hack
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,14 @@ async function json_from_file_args_async(
string $file,
Traversable<string> $parse_args,
): Awaitable<dict<string, mixed>> {
$cmd = Vec\concat(
vec['hh_parse', '--php5-compat-mode', '--full-fidelity-json'],
$args = Vec\concat(
vec['--php5-compat-mode', '--full-fidelity-json'],
vec($parse_args),
vec[$file],
);

try {
$results = await __Private\ParserQueue::get()->enqueueAndWaitForAsync(
async () ==> await __Private\execute_async(...$cmd),
);
$results = await __Private\ParserQueue::get()->waitForAsync($args);
} catch (__Private\SubprocessException $e) {
throw new HHParseError(
$file,
Expand Down

0 comments on commit e2f73e4

Please sign in to comment.