non-blocking IO with coroutines to mimic blocking IO with threads