Make things work better after errors
Pass LoopUtils to callbacks to make it easier to reschedule timeouts.
Wait for async state changes to complete
Make a separate work queue to track async operations. Keep separate work queues for links and nodes. This avoids lockups when some async operation take a long time and the work queue has SYNC_WAIT operations.