acrylic-origami / HHReactor

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

Started producer is not detached when it becomes unreachable #4

Closed acrylic-origami closed 7 years ago

acrylic-origami commented 7 years ago

Attachment should occur when the first clone begins iterating, and it does currently. Detachment is triggered by destruction, but while unstarted Producers are destructed, started ones somehow do not when they become unreachable by the calling scope. This was discovered with the help of HHReactor\Test\LifecycleTestProducer, where we can add hooks to the attachment and detachment steps of Producer:

use HHReactor\Test\LifecycleTestProducer;
async function count_up(): AsyncIterator<int> {
  for($i = 0; ; $i++) {
    await \HH\Asio\later();
    yield $i;
  }
}
function make_producer(): LifecycleTestProducer<int> {
  return LifecycleTestProducer::_create(
    count_up(),
    () ==> {}, // attachment hook
    () ==> { echo "DETACH\n"; }, // single detachment hook
    () ==> { echo "TOTAL DETACH\n"; } // total detachment hook (all running refs dropped)
  );
}

// unstarted `Producer` is destructed
\HH\Asio\join(async { 
  $producer = make_producer();
});
// expected "DETACH" and "TOTAL DETACH" echoes here
echo "End of unstarted\n-\n";

// started `Producer` isn't destructed
\HH\Asio\join(async { 
  $producer = make_producer();
  await $producer->next();
});
// silence
echo "End of test\n";

I'm concerned that the scheduler holds a reference to Producer that prevents it from being destructed — this might be an HHVM issue.