I think this is a little tricky because, using the RingBuffer as an example, it would be impossible to fulfill this requirement as-is. I would deadlock the thread if I tried to checkout another slot in the RingBuffer while in the event thread of the RingBuffer itself. The only solution to this is what we do in Reactor which is simulate tail recursion by placing a task to be dispatched onto a `Queue` that will be emptied after the current event handling method has returned.

It also doesn't seem optimal to enforce crossing a thread boundary here. When using the RingBuffer I only ever use a single thread so I can certainly make task execution asynchronous but I can't make it run in another thread (nor would I want to since I'm gaining a lot of performance by *not* context-switching).

If we're going to mandate crossing an asynchronous boundary here I think it should be fairly explicit what we expect. I don't feel like the current text does enough to explain what's expected and why.