recoilphp / recoil

Asynchronous coroutines for PHP 7.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Notify kernel of failed strands rather than allowing the exception to propagate.

jmalloc opened this issue · comments

Exceptions that propagate through an entire Recoil call-stack should not "leak" onto the PHP call-stack.
This is a fancy way of saying that the Kernel needs an "error" event, of sorts, that is triggered when a strand fails.

Ideally, the event would not be a callback, but rather the wait() function throwing a particular kind of exception. wait() can then be invoked again to resume processing of any remaining, un-errored, strands.

The original issue that led to this conclusion was:

Because ApiTrait uses ->then() in an attempt to support arbitrary promise implementations, any exceptions thrown are captured and propagate up the promise chain.

This results in the top-level ->done() handler in ReactKernel having no effect (because it's happening INSIDE the ->then() of the earlier promise. Confused?

Solutions:

  • Don't try to support generic thenables, put only specific promise handling code in the appropriate kernel implementation (ie, use >done() inside of ReactApi::dispatch() when $value is an ExtendedPromiseInterface).
  • "Escape" the promise chain by resuming the strand on the next tick. There's no kernel agnostic way to do this right now.
  • Don't allow "anything" (observers or StrandTrait::tick()) to propagate exceptions at all - instead explicitly kill the kernel with an error (much like a real multithreaded process).