acrylic-origami / HHReactor

Producer-based Reactor for Hack
MIT License
2 stars 0 forks source link

Items totally unbalanced between hot, synchronous consumers #8

Open acrylic-origami opened 7 years ago

acrylic-origami commented 7 years ago

It turns out that, thanks to the lack of proactive action to balance items for hot consumers, both HHReactor and AmpReactor suffer from the same issue. In Hack, although the scheduler "is stochastic", in 3.19 it's actually deterministic, which gives one synchronous consumer all the control when racing the others in the foreach-await.

See for yourself:

<?hh
$source = HHReactor\Producer::create(async { for($i = 0; $i < 10; $i++) { await \HH\Asio\later(); yield $i; } });
\HH\Asio\join(\HH\Asio\va(
  async { foreach($source await as $v) printf("Consumer 1: %d\n", $v); },
  async { foreach($source await as $v) printf("Consumer 2: %d\n", $v); }
));

Notice how something like the following is balanced, thanks to random deferral:


<?hh
$source = HHReactor\Producer::create(async { for($i = 0; $i < 10; $i++) { await \HH\Asio\later(); yield $i; } });
\HH\Asio\join(\HH\Asio\va(
  async { foreach($source await as $v) { printf("Consumer 1: %d\n", $v);
    if(round(mt_rand()/getrandmax())) await \HH\Asio\later();
  } },
  async { foreach($source await as $v) { printf("Consumer 2: %d\n", $v);
    if(round(mt_rand()/getrandmax())) await \HH\Asio\later(); 
  } }
));
acrylic-origami commented 7 years ago

On a side note, this seems to show that Awaitable subscribers are processed in FIFO order despite ready wait handles being processed in LIFO (as of HHVM 3.19 — subject to change).